<?php include_once($UTIL_DIR . "/convert.php"); include_once($UTIL_DIR . "/threads.php"); include_once($UTIL_DIR . "/parser.php"); class Post { public $pid; public $user; public $title; public $date; public $message; public $replies = array(); public function write($fp, $indent) { fwrite($fp, $indent . "<post pid=\"" . $this->pid . "\"\n"); fwrite($fp, $indent . " user=\"" . $this->user . "\"\n"); fwrite($fp, $indent . " title=\"" . convert_xml($this->title) . "\"\n"); fwrite($fp, $indent . " date=\"" . $this->date . "\">\n"); fwrite($fp, $indent . " <message>" . convert_xml($this->message) . "</message>\n"); foreach($this->replies as $reply) { $reply->write($fp, $indent . " "); } fwrite($fp, $indent . "</post>\n"); } public function add($post) { $key = $post->pid; $this->replies[$key] = $post; } public function getPost($pid) { $result = false; foreach($this->replies as $post) { if($post->pid == $pid) return $post; $result = $post->getPost($pid); if($result) return $result; } return $result; } public function show($indent = " ", $recurse = true) { global $users, $fid, $tid, $current_user, $client_is_mobile_device; $user = $users->getUser($this->user); echo $indent . "<div class=\"post\">\n"; if($client_is_mobile_device) { $avatar = "mobileavatar.gif"; } else { if($user->avatar) $avatar = $user->avatar; else $avatar = "default.gif"; } echo $indent . " <img class=\"avatar\" alt=\"avatar\" src=\"gfx/avatars/" . $avatar . "\"/>\n"; if(!$client_is_mobile_device) { echo $indent . " <div class=\"id\">ID: " . $this->pid . "</div>\n"; echo $indent . " <div class=\"title\">Title: " . convert_xml($this->title) . "</div>\n"; } echo $indent . " <div class=\"user\">"; if(!$client_is_mobile_device) echo "UserID: "; echo $user->name . "</div>\n"; echo $indent . " <div class=\"date\">"; if(!$client_is_mobile_device) echo "Date: "; echo date("j. M Y - G:i", $this->date) . "</div>\n"; echo $indent . " <div class=\"message\">\n"; echo parse($this->message, $indent . " ") . "\n"; if(trim($user->signature) != "") { echo $indent . " <div class=\"signature\">\n"; echo parse("--------------------------\n" . $user->signature, $indent . " ") . "\n"; echo $indent . " </div>\n"; } echo $indent . " </div>\n"; echo $indent . " <div class=\"buttons\">\n"; if($current_user->uid == $this->user) { echo $indent . " <a href=\"?mode=editor&task=edit&fid=".$fid. "&tid=".$tid. "&pid=".$this->pid."\">"; echo "<img alt=\"edit\" src=\"gfx/btn_edit.gif\"/></a>\n"; } echo $indent . " <a href=\"?mode=editor&task=quote&fid=".$fid. "&tid=".$tid. "&pid=".$this->pid."\">"; echo "<img alt=\"quote\" src=\"gfx/btn_quote.gif\"/></a>\n"; echo $indent . " <a href=\"?mode=editor&task=reply&fid=".$fid. "&tid=".$tid. "&pid=".$this->pid."\">"; echo "<img alt=\"reply\" src=\"gfx/btn_reply.gif\"/></a>\n"; echo $indent . " </div>\n"; echo $indent . " <div class=\"replies\">\n"; if($recurse) { foreach($this->replies as $reply) { $reply->show($indent . " "); } } echo $indent . " </div>\n"; echo $indent . "</div>\n"; } public function Post($pid, $title, $user, $date, $message = "") { $this->pid = $pid; $this->title = $title; $this->user = $user; $this->date = $date; $this->message = $message; } } class Posts { private $file; private $posts = array(); public $thread; private $posts_linear = array(); private $maxkey = 0; public function nextkey() { $this->maxkey++; return $this->maxkey; } public function add($post) { $key = $post->pid; $this->posts[$key] = $post; } public function write() { $fp = fopen($this->file, "w"); $block = TRUE; flock($fp, LOCK_EX, $block); // do an exclusive lock fwrite($fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); if($this->thread->lastseen) { foreach($this->thread->lastseen as $key => $value) { if($lastseenstr != "") $lastseenstr .= ","; $lastseenstr .= $key . "=" . $value; } } fwrite($fp, "<thread tid=\"" . $this->thread->tid . "\"\n"); fwrite($fp, " name=\"" . convert_xml($this->thread->name) . "\"\n"); fwrite($fp, " lastpost=\"" . $this->thread->lastpost . "\"\n"); fwrite($fp, " lastseen=\"" . $lastseenstr . "\">\n"); foreach($this->posts as $post) { $post->write($fp, " "); } fwrite($fp, "</thread>\n"); fclose($fp); } public function getPost($pid) { $result = false; foreach($this->posts as $post) { if($post->pid == $pid) return $post; $result = $post->getPost($pid); if($result) return $result; } return $result; } public function show() { global $current_user; echo " <h1 id=\"top\">" . $this->thread->name . "</h1>\n"; /* // Recursive foreach($this->posts as $post) { $post->show(); } */ // Linear $firstunread = false; foreach($this->posts_linear as $post) { if($post->date > $this->thread->lastseen[$current_user->uid] && $firstunread == false) { $firstunread = true; echo " <div id=\"firstunread\"></div>\n"; echo " <div class=\"unread\">\n"; } $post->show(" ", false); } if($firstunread == true) { echo " </div>\n"; } $this->thread->lastseen[$current_user->uid] = time(); $this->write(); echo " <p><a href=\"#top\">Back to the top</a></p>\n"; } private function recurser($parentpost, $element) { if($element->tagName != "post") return; $post = new Post($element->getAttribute('pid'), $element->getAttribute('title'), $element->getAttribute('user'), $element->getAttribute('date')); $this->posts_linear[$post->date . "-" . $post->pid] = $post; if($post->pid > $this->maxkey) $this->maxkey = $post->pid; if($parentpost) $parentpost->add($post); else $this->add($post); foreach($element->childNodes as $child) { if($child->tagName == "post") $this->recurser($post, $child); if($child->tagName == "message") $post->message = $child->textContent; } } private function read() { $dom = new DomDocument; $dom->resolveExternals = FALSE; $dom->substituteEntities = FALSE; $dom->preserveWhiteSpace = FALSE; $dom->load($this->file); $thread = $dom->documentElement; $this->thread = new Thread($thread->getAttribute('tid'), $thread->getAttribute('name'), $thread->getAttribute('lastpost'), $thread->getAttribute('lastseen')); foreach($thread->childNodes as $child) { $this->recurser(false, $child); } // The linear list should be sorted. sort($this->posts_linear); } public function Posts($file) { $this->file = $file; if(file_exists($this->file)) $this->read(); } } ?>