diff -Naur beta5//scripts/config.inc forums//scripts/config.inc
--- beta5//scripts/config.inc 2011-02-05 10:09:57.904335002 +0100
+++ forums//scripts/config.inc 2011-03-12 15:47:09.431300051 +0100
@@ -39,7 +39,7 @@
"widgetURL" => "http://www.legacyworlds.com/downloads/LegacyWorlds-Dashboard-latest.zip",
// Version numbers to make us feel good
- "v_engine" => "0.85a",
+ "v_engine" => "0.86",
"v_game" => "Beta 5",
"v_rev" => "2218",
diff -Naur beta5//scripts/game/beta5/actions/getForums.inc forums//scripts/game/beta5/actions/getForums.inc
--- beta5//scripts/game/beta5/actions/getForums.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/beta5/actions/getForums.inc 2011-02-05 10:10:03.244335002 +0100
@@ -0,0 +1,84 @@
+
+
+/** This action returns the structure of the forums a player has access to.
+ *
+ * \parameter $player The player identifier for whom to get the forums' structure
+ *
+ * \returns null on error or a fl_container instance that contains the forums' structure.
+ */
+
+class beta5_getForums {
+
+ private static $names = array(
+ 'G' => array(
+ 'en' => array('General forums', "LegacyWorlds' public forums"),
+ 'fr' => array('Forums généraux', "Les forums publics de LegacyWorlds")
+ ),
+ 'U' => array(
+ 'en' => array('Player forums', "Forums belonging to other LegacyWorlds players"),
+ 'fr' => array('Forums des joueurs', "Forums appartenant à d'autres joueurs de LegacyWorlds")
+ )
+ );
+
+ public function __construct($game) {
+ $this->game = $game;
+ $this->db = $this->game->getDBAccess();
+
+ // Load the forums' access libraries
+ $this->gForums = $this->game->getLib('main/gforums');
+ $this->uForums = $this->game->getLib('main/uforums');
+ $this->aForums = $this->game->getLib('beta5/aforums');
+
+ // Load the container class
+ loader::needClasses('main/forums', 'fl_container');
+ }
+
+ public function run( $player ) {
+ // Get the player's user ID
+ $q = $this->db->query("SELECT userid FROM player WHERE id = $1", (int) $player);
+ if (!( $q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($user) = dbFetchArray($q);
+
+ // Get the language string for the user
+ // FIXME: that thing would not work inside anything *but* a web session
+ $lang = getLanguage();
+
+ // Get the list of general, user-specific and alliance forums
+ $gForums = $this->gForums->call('getStructure', $user);
+ $aForums = $this->aForums->call('getStructure', $user);
+ $uForums = $this->uForums->call('getStructure', $user);
+
+ // Generate the container for the whole thing
+ $forums = new fl_container('/', '', '');
+
+ // Generate the container for general forums
+ $gContainer = new fl_container('G', self::$names['G'][$lang][0], self::$names['G'][$lang][1]);
+ foreach ($gForums as $gc) {
+ $gContainer->addCategory($gc);
+ }
+ $forums->addCategory($gContainer);
+
+ // Add the alliance forums
+ if (count($aForums) == 1) {
+ $forums->addCategory($aForums[0]);
+ }
+
+ // Add the player's own forums
+ $forums->addCategory(array_shift($uForums));
+
+ // Add the other players' forums
+ if (count($uForums)) {
+ $uContainer = new fl_container('U', self::$names['U'][$lang][0], self::$names['U'][$lang][1]);
+ foreach ($uForums as $uc) {
+ $uContainer->addCategory($uc);
+ }
+ $forums->addCategory($uContainer);
+ }
+
+ return $forums;
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/beta5/actions.inc forums//scripts/game/beta5/actions.inc
--- beta5//scripts/game/beta5/actions.inc 2011-02-05 10:09:57.784335002 +0100
+++ forums//scripts/game/beta5/actions.inc 2011-03-12 14:56:24.591300053 +0100
@@ -29,6 +29,10 @@
var $fleetDepartures = array();
var $ePower = array();
+ var $index = array(
+ 'getForums'
+ );
+
function actions_beta5($game) {
$this->game = $game;
diff -Naur beta5//scripts/game/beta5/aforums/library.inc forums//scripts/game/beta5/aforums/library.inc
--- beta5//scripts/game/beta5/aforums/library.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/beta5/aforums/library.inc 2011-02-05 10:10:03.334335002 +0100
@@ -0,0 +1,256 @@
+lib = $lib;
+ $this->game = $this->lib->game;
+ $this->version = $this->game->version;
+ $this->db = $this->game->db;
+
+ $this->fLib = $this->game->getLib('main/forums');
+ loader::needClasses('main/forums', array('fl_category', 'fl_forum'));
+
+ $this->getPlayerQ = $this->db->prepare(
+ "SELECT id FROM player WHERE userid = $1 AND (quit IS NULL OR quit > UNIX_TIMESTAMP(NOW()))",
+ array("user"));
+ $this->getAllianceCatQ = $this->db->prepare(
+ "SELECT a.f_category FROM player p, alliance a "
+ . "WHERE a.id = p.alliance AND p.alliance IS NOT NULL AND p.a_status='IN ' AND p.id = $1",
+ array("player") );
+ $this->getAllianceQ = $this->db->prepare(
+ "SELECT a.tag, a.name FROM alliance a WHERE a.f_category = $1",
+ array("category") );
+ $this->getCatForumsQ = $this->db->prepare(
+ "SELECT id FROM forums.t_forum WHERE category = $1 ORDER BY f_order", array("category") );
+ $this->getForumPrivQ = $this->db->prepare(
+ "SELECT * FROM get_aforums_privs( $1, $2 )", array("player", "forum") );
+ $this->getForumQ = $this->db->prepare(
+ "SELECT * FROM alliance_forum WHERE forum = $1", array("forum") );
+ $this->getForumRanksQ = $this->db->prepare(
+ "SELECT rank, is_mod FROM al_rank_forum WHERE forum = $1", array("forum") );
+ $this->getRankNameQ = $this->db->prepare(
+ "SELECT CASE name IS NULL WHEN TRUE THEN '-' ELSE name END FROM alliance_grade "
+ . "WHERE id = $1",
+ array("rank") );
+ }
+
+ public function getStructure( $user ) {
+ $cats = array();
+
+ $q = $this->getPlayerQ->execute($user);
+ if ($q && dbCount($q) == 1) {
+ list($player) = dbFetchArray($q);
+
+ $q = $this->getAllianceCatQ->execute($player);
+ if ($q && dbCount($q)) {
+ list($catId) = dbFetchArray($q);
+ $cat = $this->fLib->call('getCategory', $catId, $user);
+ if (! is_null($cat)) {
+ array_push($cats, $cat);
+ }
+ }
+ }
+
+ return $cats;
+ }
+
+ public function getCategory( $catId , $user ) {
+ $q = $this->getAllianceQ->execute($catId);
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($tag, $name) = dbFetchArray($q);
+
+ $title = "[$tag] $name";
+ $description = "These are the forums for the alliance you are a member of, $name.";
+
+ $cat = new fl_category( $this->game, $user, $catId, $title, $description );
+
+ $q = $this->getCatForumsQ->execute($catId);
+ while ($r = dbFetchArray($q)) {
+ $forum = $this->fLib->call('getForum', $r[0], $user);
+ if ($forum->canView() && ($forum->isAdmin() || ! $forum->isDeleted())) {
+ $cat->addForum( $forum );
+ }
+ }
+
+ return $cat;
+ }
+
+
+ public function getForum( $forumId, $user ) {
+ $q = $this->getPlayerQ->execute($user);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($player) = dbFetchArray($q);
+
+ $q = $this->getForumPrivQ->execute($player, $forumId);
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ $privs = dbFetchHash($q);
+
+ try {
+ $forum = new fl_forum( $this->game, $forumId, $user );
+ } catch (Exception $e) {
+ return null;
+ }
+
+ $forum->setAdmin( $privs['is_admin'] == 't' );
+ $forum->setMod( $privs['is_mod'] == 't' );
+ $forum->setCreateTopic( $privs['can_create'] == 't' );
+ $forum->setCreatePoll( $privs['can_poll'] == 't' );
+ $forum->setPost( $privs['can_post'] == 't' );
+ $forum->setView( $privs['can_view'] == 't' );
+
+ return $forum;
+ }
+
+ public function getAdmins($forum) {
+ $q = $this->getForumQ->execute($forum);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ $r = dbFetchHash($q);
+ $alliance = $r['alliance'];
+
+ if (! is_null(self::$allianceAdmins[$alliance])) {
+ return self::$allianceAdmins[$alliance];
+ }
+
+ if (is_null($this->alliance)) {
+ $this->alliance = $this->game->getLib('beta5/alliance');
+ }
+
+ $l = array_keys($this->alliance->call('getRanks', $alliance));
+ $admin = array();
+ foreach ($l as $rId) {
+ $pr = $this->alliance->call('getRankPrivileges', $rId);
+ if (! $pr['forum_admin']) {
+ continue;
+ }
+ array_push($admin, $rId);
+ }
+
+ return (self::$allianceAdmins[$alliance] = $admin);
+ }
+
+ public function getModerators($forum) {
+ $rl = $this->getRankAccess($forum);
+ $rv = array();
+ foreach ($rl as $rId => $isMod) {
+ if ($isMod) {
+ array_push($rv, $rId);
+ }
+ }
+ return $rv;
+ }
+
+ public function getUsers($forum) {
+ $rl = $this->getRankAccess($forum);
+ $rv = array();
+ foreach ($rl as $rId => $isMod) {
+ if (! $isMod) {
+ array_push($rv, $rId);
+ }
+ }
+ return $rv;
+ }
+
+
+ private function getRankAccess($forum) {
+ if (! is_null(self::$rAccess[$forum])) {
+ return self::$rAccess[$forum];
+ }
+
+ $rv = array();
+ $q = $this->getForumRanksQ->execute($forum);
+
+ if ($q && dbCount($q)) {
+ while ($r = dbFetchHash($q)) {
+ $rv[$r['rank']] = ($r['is_mod'] == 't');
+ }
+ }
+
+ return (self::$rAccess[$forum] = $rv);
+ }
+
+
+ public function aclIdToName($id) {
+ $q = $this->getRankNameQ->execute($id);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($rv) = dbFetchArray($q);
+ return $rv;
+ }
+
+
+
+ public function getUserPrivileges($forum) {
+ $q = $this->getForumQ->execute($forum);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ $r = dbFetchHash($q);
+ return $r['access_mode'];
+ }
+
+
+ public function create($player, $user, $alliance, $order, $name, $description, $accessMode) {
+ $q = $this->db->query("SELECT create_alliance_forum($1, $2, $3, $4, $5, $6)",
+ $player, $alliance, $order, $name, $description, $accessMode);
+ if (!($q && dbCount($q))) {
+ return -6;
+ }
+ list($rv) = dbFetchArray($q);
+
+ if ($rv > 0) {
+ $forum = $this->fLib->call('getForum', $rv, $user);
+ if (is_null($forum)) {
+ return -6;
+ }
+ $forum->getCategory()->insertNewForum($forum);
+ $rv = $forum;
+ } else {
+ $rv = -$rv;
+ }
+
+ return $rv;
+ }
+
+ public function modifyForum($forum, $player, $name, $description, $accessMode) {
+ $this->db->query("SELECT modify_alliance_forum($1,$2,$3,$4,$5)",
+ $player, $forum, $name, $description, $accessMode);
+ if (!($q && dbCount($q))) {
+ return -5;
+ }
+ list($rv) = dbFetchArray($q);
+ return $rv;
+ }
+
+ public function clearForumACL($forum) {
+ $this->db->query("DELETE FROM al_rank_forum WHERE forum = $1", $forum);
+ }
+
+ public function addForumModerator( $forum, $id ) {
+ $this->db->query("INSERT INTO al_rank_forum (rank, forum, is_mod) VALUES ($1, $2, TRUE)",
+ $id, $forum);
+ }
+
+ public function addForumUser( $forum, $id ) {
+ $this->db->query("INSERT INTO al_rank_forum (rank, forum, is_mod) VALUES ($1, $2, FALSE)",
+ $id, $forum);
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/beta5/forums/topic/library.inc forums//scripts/game/beta5/forums/topic/library.inc
--- beta5//scripts/game/beta5/forums/topic/library.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/beta5/forums/topic/library.inc 2011-02-05 10:10:03.334335002 +0100
@@ -0,0 +1,330 @@
+
+
+class beta5_forums_topic_library {
+
+ private $pHandler;
+ private $lib;
+ private $game;
+ private $topic = null;
+ private $deleted = false;
+
+ public function __construct($lib) {
+ $this->lib = $lib;
+ $this->game = $this->lib->game;
+ }
+
+ public function initialize($pageHandler) {
+ $this->pHandler = $pageHandler;
+ }
+
+ public function forumCommand($player, $commandArgs) {
+
+ // Read the arguments
+ if (strstr($commandArgs, "#") !== FALSE) {
+ list( $topicIdS, $hexId ) = explode('#', $commandArgs);
+ if (strlen($hexId) != 32 || preg_match('/[^A-Z0-9]/i', $hexId)) {
+ $hexId = md5(uniqid(rand()));
+ }
+
+ $topicId = (int) $topicIdS;
+ $data = $this->pHandler->getSessionData('topic_' . $hexId);
+ if (is_null($data) || $topicId != $data['topic']) {
+ $hexId = md5(uniqid(rand()));
+ $firstTime = true;
+ } else {
+ $firstTime = false;
+ }
+ } else {
+ $topicId = (int) $commandArgs;
+ $hexId = md5(uniqid(rand()));
+ $firstTime = true;
+ }
+
+ // Get the player's user ID
+ $pinf = $this->game->getLib('beta5/player')->call('get', $player);
+ $user = $pinf['uid'];
+
+ if ($firstTime) {
+ $this->game->action('getForums', $player);
+ $data = $this->initTopicData($user, $topicId);
+ $this->makeDataString($data, $hexId);
+ } else {
+ $this->updateTopicData($topicId, $data);
+ }
+ $this->pHandler->setSessionData('topic_' . $hexId, $data);
+ $this->data = $data;
+
+ if ($data['exists']) {
+ $rv = array("V#F#{$data['forum']}", "vTopic", "$topicId#$hexId");
+ } else {
+ $rv = array("", "vTopic", "$topicId#$hexId");
+ }
+ return $rv;
+ }
+
+
+ /* This method initialises the stored session data for the specified topic ID.
+ */
+ private function initTopicData($user, $topicId) {
+ $data = array(
+ "viewTime" => time(),
+ "topic" => $topicId,
+ "user" => $user
+ );
+
+ // Check whether the topic actually exists
+ $topic = $this->game->getLib('main/forums')->call('getTopic', $topicId, $user);
+ if (is_null($topic)) {
+ $data['exists'] = false;
+ return $data;
+ }
+
+ // Check whether the topic is available
+ $forum = $this->forum = $topic->getForum();
+ if (is_null($forum) || ! $forum->canView()) {
+ $data['exists'] = false;
+ return $data;
+ }
+
+ // The topic exists
+ $data['exists'] = true;
+ $data['forum'] = $forum->getId();
+ $data['title'] = $topic->getTitle();
+
+ // Has it been deleted?
+ if ($topic->isDeleted()) {
+ $data['deleted'] = true;
+ $data['deletedAt'] = $topic->getDeletionTime();
+ $data['deletedBy'] = $topic->getDeletionMod();
+ return $data;
+ }
+
+ // Get additional data
+ $users = array();
+ $data['lastChange'] = $topic->getLastChange();
+ $data['lastRead'] = $topic->getLastRead();
+ $data['isLocked'] = $topic->isLocked();
+ $data['isMod'] = $forum->isMod();
+ $data['canPost'] = $forum->canPost();
+
+ // Get the topic's posts
+ $data['postOrder'] = array();
+
+ // -> linear, newest first
+ $list = $topic->getPostList(false, false);
+ $data['postOrder']['ln'] = array();
+ foreach ($list as $p) {
+ array_push($data['postOrder']['ln'], $p->getId());
+ }
+
+ // -> linear, oldest first
+ $list = $topic->getPostList(false, true);
+ $data['postOrder']['lo'] = array();
+ foreach ($list as $p) {
+ array_push($data['postOrder']['lo'], $p->getId());
+ }
+
+ // -> threaded, newest first
+ $list = $topic->getPostList(true, false);
+ $data['postOrder']['tn'] = array();
+ foreach ($list as $p) {
+ array_push($data['postOrder']['tn'], $p->getId());
+ }
+
+ // -> threaded, oldest first
+ $list = $topic->getPostList(true, true);
+ $data['postOrder']['to'] = array();
+ foreach ($list as $p) {
+ array_push($data['postOrder']['to'], $p->getId());
+ }
+
+ // -> post data
+ $data['posts'] = array();
+ foreach ($list as $p) {
+ // post_id # depth # author_id # posted_at # is_unread # lc_time # lc_author
+ // post_title
+ $pStr = $p->getId() . "#" . $p->getDepth() . "#" . $p->getPostedBy()
+ . "#" . $p->getPostedAt() . "#" . ($p->isUnread() ? 1 : 0)
+ . "#" . $p->getLastChange() . "#" . $p->getLastChangeAuthor()
+ . "\n" . utf8entities($p->getTitle());
+ array_push($data['posts'], $pStr);
+ if (!in_array($p->getPostedBy(), $users)) {
+ array_push($users, $p->getPostedBy());
+ }
+ if (!(is_null($p->getLastChangeAuthor()) || in_array($p->getLastChangeAuthor(), $users))) {
+ array_push($users, $p->getLastChangeAuthor());
+ }
+ }
+
+ // Get poll data
+ $poll = $topic->getPoll();
+ $data['hasPoll'] = ! is_null($poll);
+ if ($data['hasPoll']) {
+ // FIXME: get poll data
+ }
+
+ // Get user names
+ $data['users'] = $this->dumpNames($users);
+
+ return $data;
+ }
+
+ private function dumpNames($ids) {
+ $accLib = $this->game->getLib('main/account');
+
+ $output = array();
+ array_push($output, count($ids));
+ foreach ($ids as $id) {
+ array_push($output, "$id#" . utf8entities($accLib->call('getUserName', $id)));
+ }
+ return $output;
+ }
+
+ /* This method generates the data string to be sent the first time a topic
+ * page is loaded.
+ */
+ private function makeDataString(&$data, $hexId) {
+ $result = array(
+ "{$data['topic']}#$hexId"
+ );
+ if ($data['exists']) {
+ // Fetch the path to the topic
+ $parents = array();
+ $obj = $this->forum;
+ do {
+ array_push($parents, array(
+ $obj->getId(), utf8entities($obj->getTitle())
+ ));
+ $obj = $obj->getParent();
+ } while (! is_null($obj));
+
+ if ($data['deleted']) {
+ // If the topic has been deleted
+ array_push($result, "DELETED#{$data['deletedAt']}#" . count($parents));
+ array_push($result, utf8entities($data['title']));
+ // FIXME: fetch moderator's name
+// array_push($result, $this->game->getLib('
+
+ // Dump the path
+ foreach (array_reverse($parents) as $p) {
+ array_push($result, join('#', $p));
+ }
+
+ } else {
+ // If the topic is available
+ array_push($result, "TOPIC#" . count($parents));
+ array_push($result, utf8entities($data['title']));
+ array_push($result, "{$data['user']}#" . ($data['isMod'] ? 1 : 0)
+ . "#" . ($data['canPost'] ? 1 : 0) . "#" . ($data['hasPoll'] ? 1 : 0));
+
+ // Dump the path
+ foreach (array_reverse($parents) as $p) {
+ array_push($result, join('#', $p));
+ }
+
+ // Post orders
+ array_push($result, join('#', $data['postOrder']['ln']));
+ array_push($result, join('#', $data['postOrder']['lo']));
+ array_push($result, join('#', $data['postOrder']['tn']));
+ array_push($result, join('#', $data['postOrder']['to']));
+
+ // Posts
+ foreach ($data['posts'] as $post) {
+ array_push($result, $post);
+ }
+
+ // Users
+ foreach ($data['users'] as $user) {
+ array_push($result, $user);
+ }
+
+ // Get the viewing options
+ array_push($result, join('#', $this->getOptions($data['topic'])));
+ }
+ } else {
+ array_push($result, "MEH");
+ }
+
+ $data['initString'] = join("\n", $result);
+ }
+
+ /** This method checks for updates on the topic */
+ private function updateTopicData($topicId, &$data) {
+ $this->topic = $topic = $this->game->getLib('main/forums')->call('getTopic', $topicId, $user);
+ if (is_null($topic)) {
+ $data['stillExists'] = false;
+ return $data;
+ }
+
+ // Check whether the topic is available
+ $forum = $this->forum = $topic->getForum();
+ if (is_null($forum) || ! $forum->canView()) {
+ $data['stillExists'] = false;
+ return $data;
+ }
+
+ // The topic exists
+ $data['stillExists'] = true;
+
+ // Has it been deleted?
+ if ($topic->isDeleted()) {
+ $data['nowDeleted'] = true;
+ $data['deletedAt'] = $topic->getDeletionTime();
+ $data['deletedBy'] = $topic->getDeletionMod();
+ return $data;
+ }
+
+ // Topic hasn't been deleted, check for updates
+ $data['lastChange'] = $topic->getLastChange();
+ }
+
+ public function getData() {
+ if (is_null($this->data['updateString'])) {
+ return $this->data['initString'];
+ }
+ }
+
+
+ private function getOptions( $id ) {
+ if (! is_null($this->forum)) {
+ $isMod = $this->forum->isMod();
+ } else {
+ $isMod = false;
+ }
+
+ // perPage = posts / page, default 50, possible values 25 50 75 100
+ $perPage = prefs::get("main/T#PP#$id", prefs::get("main/T#PP", 50));
+ // vDeleted = view deleted posts, default "no"
+ $vDeleted = $isMod ? prefs::get("main/T#VD#$id", prefs::get("main/T#VD", 0)) : 0;
+ // threaded = enable threaded mode, default "yes"
+ $threaded = prefs::get("main/T#TV#$id", prefs::get("main/T#TV", 1));
+ // order = show oldest posts first, default "no"
+ $order = prefs::get("main/T#PO#$id", prefs::get("main/T#PO", 0));
+ // openPosts = posts open by default, default 1, possible values 0: none, 1: new only, 2: all
+ $openPosts = prefs::get("main/T#OP#$id", prefs::get("main/T#OP", 1));
+
+ return array($perPage, $vDeleted, $threaded, $order, $openPosts);
+ }
+
+
+ public function getPostContents($postId) {
+ $postId = (int) $postId;
+ if (! ($this->data['exists'] && $this->data['stillExists'])) {
+ return "-#$postId";
+ }
+
+ $post = $this->topic->getPostById($postId);
+ if (is_null($post)) {
+ return "-#$postId";
+ }
+
+ $contents = $this->game->getLib('main/forums')->call('substitute',
+ $post->getContents($this->data['viewTime']),
+ $post->codeEnabled($this->data['viewTime'])
+ );
+
+ return "+#$postId\n$contents";
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/beta5/forums/view/library.inc forums//scripts/game/beta5/forums/view/library.inc
--- beta5//scripts/game/beta5/forums/view/library.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/beta5/forums/view/library.inc 2011-02-05 10:10:03.334335002 +0100
@@ -0,0 +1,405 @@
+
+
+class beta5_forums_view_library {
+
+ private $pHandler;
+ private $lib;
+ private $game;
+ private $fStructure;
+ private $displayObject;
+
+ public function __construct($lib) {
+ $this->lib = $lib;
+ $this->game = $this->lib->game;
+ }
+
+ public function initialize($pageHandler) {
+ $this->pHandler = $pageHandler;
+ }
+
+ public function forumCommand($player, $commandArgs) {
+ // Examine the arguments
+ $args = explode('#', $commandArgs);
+ if (count($args) != 2 || ! in_array($args[0], array('F', 'C'))) {
+ $args = array('C', '/');
+ }
+
+ // Try to find the requested object
+ $this->fStructure = $this->game->action('getForums', $player);
+ if ($args[0] == 'C') {
+ $this->displayObject = $this->fStructure->findCategory($args[1]);
+ } else {
+ $this->displayObject = $this->fStructure->findForum($args[1]);
+ if (! is_null($this->displayObject) && (
+ ($this->displayObject->isDeleted() && ! $this->displayObject->isAdmin())
+ || ! $this->displayObject->canView()) ) {
+ $this->displayObject = null;
+ }
+ }
+ if (is_null($this->displayObject)) {
+ $this->displayObject = $this->fStructure;
+ $args = array('C', '/');
+ }
+
+ $view = join('#', $args);
+ return array("V#$view", $args[0] == 'C' ? 'vCat' : 'vForum', $view);
+ }
+
+ public function getData($oldMD5 = null) {
+ if (is_null($this->displayObject)) {
+ $r = null;
+ } else {
+ if ($this->displayObject instanceof fl_forum) {
+ $r = $this->getForumData();
+ } else {
+ $r = $this->getCategoryData();
+ }
+ $md5 = md5(serialize($r));
+ if ($md5 != $oldMD5) {
+ array_unshift($r, $md5);
+ $r = join("\n", $r);
+ } else {
+ $r = '-';
+ }
+ }
+ return $r;
+ }
+
+ public function categoryRead($category) {
+ if (is_null($this->displayObject)) {
+ return;
+ }
+
+ $cat = $this->displayObject->findCategory((int) $category);
+ if (is_null($cat) || ! ($cat instanceof fl_category)) {
+ return;
+ }
+ $cat->markRead();
+ }
+
+ public function forumRead() {
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum ) {
+ return;
+ }
+
+ $this->displayObject->markRead();
+ }
+
+ public function restoreTopics($topicList) {
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum
+ || ! $this->displayObject->isMod() ) {
+ return;
+ }
+
+ foreach ($topicList as $topicId) {
+ $topic = $this->displayObject->findTopic($topicId);
+ if (! is_null($topic) && $topic->isInForum($this->displayObject)) {
+ $topic->restore();
+ }
+ }
+ $this->displayObject->refresh();
+ }
+
+ public function deleteTopics($topicList) {
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum
+ || ! $this->displayObject->isMod() ) {
+ return;
+ }
+
+ foreach ($topicList as $topicId) {
+ $topic = $this->displayObject->findTopic($topicId);
+ if (!is_null($topic) && $topic->isInForum($this->displayObject)) {
+ $topic->delete();
+ }
+ }
+ $this->displayObject->refresh();
+ }
+
+ public function changeTopicsLevel($topicList, $change) {
+ $change = (int) $change;
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum
+ || ! $this->displayObject->isMod() || $change != -1 && $change != 1 ) {
+ return;
+ }
+
+ foreach ($topicList as $topicId) {
+ $topic = $this->displayObject->findTopic($topicId);
+ if (!is_null($topic) && $topic->isInForum($this->displayObject)) {
+ $topic->setStickyLevel($topic->getStickyLevel() + $change);
+ }
+ }
+ $this->displayObject->refresh();
+ }
+
+ public function setTopicsLevel($topicList, $level) {
+ $level = (int) $level;
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum
+ || ! $this->displayObject->isMod() || $level < 0 || $level > 10) {
+ return;
+ }
+
+ foreach ($topicList as $topicId) {
+ $topic = $this->displayObject->findTopic($topicId);
+ if (!is_null($topic) && $topic->isInForum($this->displayObject)) {
+ $topic->setStickyLevel($level);
+ }
+ }
+ $this->displayObject->refresh();
+ }
+
+ public function setTopicsLock($topicList, $lock) {
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum
+ || ! $this->displayObject->isMod()) {
+ return;
+ }
+
+ foreach ($topicList as $topicId) {
+ $topic = $this->displayObject->findTopic($topicId);
+ if (!is_null($topic) && $topic->isInForum($this->displayObject)) {
+ $topic->setLock($lock);
+ }
+ }
+ }
+
+ public function moveTopics($topicList, $destId) {
+ if (is_null($this->displayObject) || ! $this->displayObject instanceof fl_forum
+ || ! $this->displayObject->isMod() || $destId == $this->displayObject->getId()) {
+ return;
+ }
+
+ $destination = $this->fStructure->findForum((int) $destId);
+ if (is_null($destination) || ! $destination->isMod()) {
+ return;
+ }
+
+ foreach ($topicList as $topicId) {
+ $topic = $this->displayObject->findTopic($topicId);
+ if (! is_null($topic) && $topic->isInForum($this->displayObject)) {
+ $topic->moveTo($destination);
+ }
+ }
+ $this->displayObject->refresh();
+ $destination->refresh();
+ }
+
+
+ private function dumpNames(&$output, $ids) {
+ $accLib = $this->game->getLib('main/account');
+
+ array_push($output, count($ids));
+ foreach ($ids as $id) {
+ array_push($output, "$id#" . utf8entities($accLib->call('getUserName', $id)));
+ }
+ }
+
+ private function getCategoryData() {
+ $output = array(
+ "C#" . $this->displayObject->getId()
+ );
+ $namesNeeded = array();
+
+ $this->dumpCategory( &$output, &$namesNeeded, $this->displayObject );
+ $this->dumpNames( &$output, $namesNeeded );
+
+ return $output;
+ }
+
+ private function dumpCategory( &$output, &$namesNeeded, $object ) {
+ if ( $object instanceof fl_container ) {
+ $contents = $object->getCategories();
+ $type = 'C';
+ } else {
+ $contents = array();
+ foreach ($object->getForums() as $forum) {
+ if ($forum->canView() && ($forum->isAdmin() || ! $forum->isDeleted())) {
+ array_push($contents, $forum);
+ }
+ }
+ $type = 'F';
+ }
+
+ $fullDesc = explode("\n", $object->getDescription());
+ $hasUnread = ($object->getUnread() > 0) ? 1 : 0;
+ array_push( $output, $object->getId() . "#$type#$hasUnread#"
+ . count($contents) . "#" . count($fullDesc) );
+ if ($type == 'F') {
+ array_push( $output, $object->getTypeName(getLanguage()) ); // FIXME getLanguage() ...
+ }
+ array_push( $output, utf8entities($object->getTitle()) );
+ foreach ($fullDesc as $dLine ) {
+ array_push( $output, utf8entities($dLine) );
+ }
+
+ if ( $object instanceof fl_container ) {
+ foreach ($contents as $cat) {
+ $this->dumpCategory( &$output, &$namesNeeded, $cat );
+ }
+ } else {
+ foreach ($contents as $forum) {
+ $this->dumpCatForum( &$output, &$namesNeeded, $forum );
+ }
+ }
+ }
+
+ private function dumpCatForum( &$output, &$namesNeeded, $forum ) {
+ $fullDesc = explode("\n", $forum->getDescription());
+
+ $deleted = $forum->isDeleted() ? '1' : '0';
+ $deletedAt = $forum->deletedAt();
+ $deletedBy = $forum->deletedBy();
+ if (! (is_null($deletedBy) || in_array($deletedBy, $namesNeeded))) {
+ array_push($namesNeeded, $deletedBy);
+ }
+
+ $topics = $forum->getTopics();
+ $posts = is_null($lp = $forum->getLastPost()) ? 0 : $forum->getPosts();
+ $unread = ($forum->getUnread() > 0 ? 1 : 0);
+
+ array_push( $output, $forum->getId() . "#" . count($fullDesc)
+ . "#$deleted#$deletedAt#$deletedBy#$topics#$posts#$unread" );
+
+ if ($posts != 0 && !is_null($lp)) {
+ $moment = $lp->getLastChange();
+ $author = $lp->getLastChangeAuthor();
+ if (! in_array($author, $namesNeeded) ) {
+ array_push($namesNeeded, $author);
+ }
+ array_push( $output, "$author#$moment" );
+ }
+
+ array_push( $output, utf8entities($forum->getTitle()) );
+ foreach ($fullDesc as $dLine ) {
+ array_push( $output, utf8entities($dLine) );
+ }
+ }
+
+ private function getForumData() {
+ $output = array(
+ "F#" . $this->displayObject->getId()
+ );
+ $namesNeeded = array();
+ $fob = $this->displayObject;
+ $id = $fob->getId();
+
+ $perPage = prefs::get("main/F#PP#$id", prefs::get("main/F#PP", 10));
+ $vDeleted = $fob->isMod() ? prefs::get("main/F#VD#$id", prefs::get("main/F#VD", 0)) : 0;
+
+ $rTopics = $fob->getTopicList();
+ $topics = array();
+ foreach ($rTopics as $topic) {
+ if ( ! ($topic->isInForum($fob) || !is_null($topic->getForum()) && $topic->getForum()->canView())
+ || ($topic->isDeleted() && ! $vDeleted) ) {
+ continue;
+ }
+ array_push($topics, $topic);
+ }
+
+ $nTopics = count($topics);
+ $hasUnread = ($fob->getUnread() > 0) ? 1 : 0;
+ $isMod = $fob->isMod() ? 1 : 0;
+ $canPost = $fob->canCreateTopic() ? 1 : 0;
+ $fDesc = explode("\n", $fob->getDescription());
+ $admins = $fob->getAdministrators(true);
+ $mods = $fob->getModerators(true);
+ $users = $fob->getUsers(true);
+
+ if ($fob->isMod()) {
+ $fMoveTo = array();
+ $list = $this->fStructure->findModForums();
+ foreach ($list as $forum) {
+ $fId = $forum->getId();
+ if ($fId == $id) {
+ continue;
+ }
+ $fName = array($forum->getParent()->getTitle(), $forum->getTitle());
+ array_push($fMoveTo, "$fId#" . utf8entities(join(' > ', $fName)));
+ }
+ }
+
+ $parents = array();
+ $obj = $fob->getParent();
+ do {
+ array_push($parents, array(
+ $obj->getId(), utf8entities($obj->getTitle())
+ ));
+ $obj = $obj->getParent();
+ } while (! is_null($obj));
+
+ array_push($output, "$id#$nTopics#$hasUnread#$isMod#$canPost#$perPage#$vDeleted#" . count($fDesc)
+ . "#" . count($parents) . "#" . count($admins) . "#" . count($mods)
+ . "#" . count($users) . ($isMod ? ("#" . count($fMoveTo)) : ""));
+ array_push($output, utf8entities($fob->getTitle()));
+
+ // Dump description
+ foreach ($fDesc as $dLine) {
+ array_push($output, utf8entities($dLine));
+ }
+ // Parent categories
+ foreach (array_reverse($parents) as $p) {
+ array_push($output, join('#', $p));
+ }
+ // Administrators
+ foreach ($admins as $name) {
+ array_push($output, utf8entities($name));
+ }
+ // Moderators
+ foreach ($mods as $name) {
+ array_push($output, utf8entities($name));
+ }
+ // Users
+ foreach ($users as $name) {
+ array_push($output, utf8entities($name));
+ }
+ // List of forums one can move a topic to
+ if ($isMod) {
+ foreach ($fMoveTo as $l) {
+ array_push($output, $l);
+ }
+ }
+
+ foreach ($topics as $topic) {
+ if ($topic->isDeleted() && ! $vDeleted) {
+ continue;
+ }
+
+ $tid = $topic->getId();
+ $movedTo = $topic->isInForum($fob) ? '' : $topic->getForum()->getId();
+ $unread = ($topic->getLastRead() < $topic->getLastChange()) ? 1 : 0;
+ $sticky = $topic->getStickyLevel();
+ $tReplies = $topic->getPosts() - 1;
+
+ $fpTime = $topic->getPosted();
+ $fpAuth = $topic->getAuthor();
+ if (! (is_null($fpAuth) || in_array($fpAuth, $namesNeeded))) {
+ array_push($namesNeeded, $fpAuth);
+ }
+ $lcTime = $topic->getLastChange();
+ $lcAuth = $topic->getLastChangeAuthor();
+ if (! (is_null($lcAuth) || in_array($lcAuth, $namesNeeded))) {
+ array_push($namesNeeded, $lcAuth);
+ }
+
+ $isLocked = $topic->isLocked() ? 1 : 0;
+ $hasPoll = is_null($topic->getPoll()) ? 0 : 1;
+
+ $isDeleted = $topic->isDeleted() ? 1 : 0;
+ $deletedAt = $topic->getDeletionTime();
+ $deletedBy = $topic->getDeletionMod();
+ if (! (is_null($deletedBy) || in_array($deletedBy, $namesNeeded))) {
+ array_push($namesNeeded, $deletedBy);
+ }
+
+ array_push($output, "$tid#$movedTo#$unread#$sticky#$tReplies#$fpTime#$fpAuth#$lcTime#$lcAuth"
+ . "#$isLocked#$hasPoll#$isDeleted#$deletedAt#$deletedBy");
+ array_push($output, utf8entities($topic->getTitle()));
+ if ($movedTo != '') {
+ array_push($output, utf8entities($topic->getForum()->getTitle()));
+ }
+ }
+
+ $this->dumpNames( &$output, $namesNeeded );
+ return $output;
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/main/forums/fl_category.inc forums//scripts/game/main/forums/fl_category.inc
--- beta5//scripts/game/main/forums/fl_category.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/forums/fl_category.inc 2011-02-05 10:10:03.434335002 +0100
@@ -0,0 +1,270 @@
+game = $game;
+ $this->db = $this->game->getDBAccess();
+
+ $this->user = $user;
+ $this->id = $id;
+ $this->title = $title;
+ $this->description = $description;
+ }
+
+ private static function initQueries() {
+ if (!is_null(self::$getLibQuery)) {
+ return;
+ }
+
+ $db = config::getMainInterface()->getDBAccess();
+ self::$getLibQuery = $db->prepare(
+ "SELECT t.id AS id,t.lib_path AS path "
+ . "FROM forums.category_type t, forums.category c "
+ . "WHERE c.id = $1 AND t.id = c.acl_lib",
+ array("id") );
+ self::$getNameQuery = $db->prepare(
+ "SELECT name FROM forums.cat_type_text "
+ . "WHERE id = $1 AND lang = $2",
+ array("id", "lang") );
+ }
+
+ public function findCategory( $catId ) {
+ if ($this->getId() == $catId) {
+ return $this;
+ }
+ return null;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // READING CATEGORY PROPERTIES
+ // ----------------------------------------------------------------------
+
+ public function getId() {
+ return $this->id;
+ }
+
+ public function getTitle() {
+ return $this->title;
+ }
+
+ public function getDescription() {
+ return $this->description;
+ }
+
+ public function getLibrary() {
+ if (is_null($this->hdlLib)) {
+ $q = self::$getLibQuery->execute(array("id" => $this->id));
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+
+ $r = dbFetchHash($q);
+ $r['library'] = $this->game->getLib($r['path']);
+ $r['text'] = array();
+ $this->hdlLib = $r;
+ }
+ return $this->hdlLib['library'];
+ }
+
+ public function getTypeName($lang) {
+ if (is_null($this->hdlLib)) {
+ if (is_null($this->getLibrary())) {
+ return null;
+ }
+ }
+
+ if (! isset($this->hdlLib['text'][$lang]) ) {
+ $q = self::$getNameQuery->execute(array(
+ "id" => $this->hdlLib['id'],
+ "lang" => $lang
+ ));
+ if (! ($q || dbCount($q) == 1)) {
+ return null;
+ }
+ list($this->hdlLib['text'][$lang]) = dbFetchArray($q);
+ }
+
+ return $this->hdlLib['text'][$lang];
+ }
+
+ public function getUnread( ) {
+ if (!is_null($this->unread)) {
+ return $this->unread;
+ }
+
+ $total = 0;
+ foreach ($this->forums as $f) {
+ if ( $f->canView() && ! $f->isDeleted() ) {
+ $total += $f->getUnread();
+ }
+ }
+ return ($this->unread = $total);
+ }
+
+ public function getTopics( ) {
+ if (!is_null($this->topics)) {
+ return $this->topics;
+ }
+
+ $total = 0;
+ foreach ($this->forums as $f) {
+ if ( $f->canView() && ! $f->isDeleted() ) {
+ $total += $f->getTopics();
+ }
+ }
+ return ($this->topics = $total);
+ }
+
+ public function getPosts( ) {
+ if (!is_null($this->posts)) {
+ return $this->posts;
+ }
+
+ $total = 0;
+ foreach ($this->forums as $f) {
+ if ( $f->canView() && ! $f->isDeleted() ) {
+ $total += $f->getPosts();
+ }
+ }
+ return ($this->posts = $total);
+ }
+
+ public function setParent( $category ) {
+ $this->parent = $category;
+ }
+
+ public function getParent() {
+ return $this->parent;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // FORUM ACCESS
+ // ----------------------------------------------------------------------
+
+ public function getForums() {
+ return $this->oForums;
+ }
+
+ public function findModForums() {
+ $r = array();
+ foreach ($this->oForums as $f) {
+ if ($f->isMod()) {
+ array_push($r, $f);
+ }
+ }
+ return $r;
+ }
+
+ public function addForum( $forum ) {
+ if (is_null($forum)) {
+ return;
+ }
+ $this->forums[(string) $forum->getId()] = $forum;
+ array_push($this->oForums, $forum);
+ $forum->setParent($this);
+ }
+
+ public function insertNewForum($forum) {
+ if (isset($this->forums[$id])) {
+ return;
+ }
+
+ $this->forums[$forum->getId()] = $forum;
+ $forum->setParent($this);
+ $order = array();
+ for ($i = 0; $i < count($this->oForums); $i ++) {
+ if ($i == $forum->getOrder()) {
+ array_push($order, $forum);
+ }
+ if ($i >= $forum->getOrder()) {
+ $this->oForums[$i]->increaseOrder();
+ }
+ array_push($order, $this->oForums[$i]);
+ }
+ if ($i == $forum->getOrder()) {
+ array_push($order, $forum);
+ }
+ $this->oForums = $order;
+ }
+
+ public function findForum( $id ) {
+ return isset($this->forums[$id]) ? $this->forums[$id] : null;
+ }
+
+ public function moveForum( $id, $moveUp ) {
+ if (!isset($this->forums[$id])) {
+ return false;
+ }
+
+ $qs = "SELECT forums.move_" . ($moveUp ? 'up' : 'down') . '($1)';
+ $q = $this->db->query($qs, $id);
+ if (! ($q && dbCount($q))) {
+ return false;
+ }
+ list($rc) = dbFetchArray($q);
+
+ if ($rc == 't') {
+ $n = count($this->oForums);
+ for ($i = 0; $i < $n; $i ++) {
+ if ($this->oForums[$i]->getId() == $id) {
+ if ($moveUp) {
+ $rv = $this->oForums[$i - 1];
+ $this->oForums[$i - 1] = $this->oForums[$i];
+ $this->oForums[$i] = $rv;
+ } else {
+ $rv = $this->oForums[$i + 1];
+ $this->oForums[$i + 1] = $this->oForums[$i];
+ $this->oForums[$i] = $rv;
+ }
+ break;
+ }
+ }
+ } else {
+ $rv = false;
+ }
+
+ return $rv;
+ }
+
+ public function markRead() {
+ foreach ($this->oForums as $forum) {
+ $forum->markRead();
+ }
+ }
+
+ public function refresh() {
+ $this->unread = $this->topics = $this->posts = null;
+ if ($this->parent) {
+ $this->parent->refresh();
+ }
+ }
+}
+
+
+?>
diff -Naur beta5//scripts/game/main/forums/fl_container.inc forums//scripts/game/main/forums/fl_container.inc
--- beta5//scripts/game/main/forums/fl_container.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/forums/fl_container.inc 2011-02-05 10:10:03.434335002 +0100
@@ -0,0 +1,116 @@
+id = $id;
+ $this->title = $title;
+ $this->description = $description;
+ }
+
+ public function addCategory( $category ) {
+ if (! is_null($category)) {
+ array_push($this->categories, $category);
+ $category->setParent( $this );
+ }
+ }
+
+ public function setParent( $category ) {
+ $this->parent = $category;
+ }
+
+ public function getParent() {
+ return $this->parent;
+ }
+
+ public function getCategories() {
+ return $this->categories;
+ }
+
+ public function getId() {
+ return $this->id;
+ }
+
+ public function getTitle() {
+ return $this->title;
+ }
+
+ public function getDescription() {
+ return $this->description;
+ }
+
+ public function getUnread( ) {
+ if (!is_null($this->unread)) {
+ return $this->unread;
+ }
+
+ $total = 0;
+ foreach ($this->categories as $c) {
+ $total += $c->getUnread();
+ }
+ return ($this->unread = $total);
+ }
+
+ public function getTopics( ) {
+ if (!is_null($this->topics)) {
+ return $this->topics;
+ }
+
+ $total = 0;
+ foreach ($this->categories as $c) {
+ $total += $c->getTopics();
+ }
+ return ($this->topics = $total);
+ }
+
+ public function findCategory( $catId ) {
+ if ($this->getId() == $catId) {
+ return $this;
+ }
+ foreach ($this->categories as $cat) {
+ $x = $cat->findCategory( $catId );
+ if (! is_null($x)) {
+ return $x;
+ }
+ }
+ return null;
+ }
+
+ public function findForum( $fId ) {
+ foreach ($this->categories as $cat) {
+ $x = $cat->findForum( $fId );
+ if (! is_null($x)) {
+ return $x;
+ }
+ }
+ return null;
+ }
+
+ public function findModForums() {
+ $r = array();
+ foreach ($this->categories as $cat) {
+ $r = array_merge($r, $cat->findModForums());
+ }
+ return $r;
+ }
+
+ public function refresh() {
+ $this->unread = $this->topics = null;
+ if ($this->parent) {
+ $this->parent->refresh();
+ }
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/main/forums/fl_forum.inc forums//scripts/game/main/forums/fl_forum.inc
--- beta5//scripts/game/main/forums/fl_forum.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/forums/fl_forum.inc 2011-02-05 10:10:03.434335002 +0100
@@ -0,0 +1,533 @@
+ array(),
+ "mods" => array(),
+ "users" => array()
+ );
+
+ public function __construct($game, $id, $user) {
+ self::initQueries();
+
+ $this->game = $game;
+ $this->db = $this->game->getDBAccess();
+ $this->user = $user;
+
+ $q = self::$queries['getInfo']->execute($id);
+ if (! ($q && dbCount($q) == 1)) {
+ throw new Exception("Unable to read forum record");
+ }
+ $this->record = dbFetchHash($q);
+
+ $this->privs = array(
+ 'adm' => false,
+ 'mod' => false,
+ 'ntop' => false,
+ 'poll' => false,
+ 'post' => false,
+ 'view' => false
+ );
+ }
+
+
+ private static function initQueries() {
+ if (is_array(self::$queries)) {
+ return;
+ }
+
+ $db = config::getMainInterface()->getDBAccess();
+
+ self::$queries['getInfo'] = $db->prepare(
+ "SELECT * FROM forums.forum WHERE id = $1",
+ array("id") );
+ self::$queries['getRead'] = $db->prepare(
+ "SELECT forums.get_read_topics( $1 , $2 )",
+ array("forum", "user") );
+ self::$queries['getCurrentSig'] = $db->prepare(
+ "SELECT id FROM forums.get_signature( $1, UNIX_TIMESTAMP(NOW()) )",
+ array("user") );
+ self::$queries['createTopic'] = $db->prepare(
+ "SELECT forums.create_topic($1, $2, $3, $4, $5, $6, $7, $8)",
+ array("forum", "user", "sticky", "title", "contents", "code", "smileys", "sig") );
+ self::$queries['killTopic'] = $db->prepare(
+ "DELETE FROM forums.t_topic WHERE id = $1",
+ array("topic") );
+ self::$queries['getTopics'] = $db->prepare(
+ "SELECT * FROM forums.topic WHERE forum = $1 OR moved_from = $1",
+ array("forum") );
+ }
+
+
+ // ----------------------------------------------------------------------
+ // READING FORUM PROPERTIES
+ // ----------------------------------------------------------------------
+
+ public function getId() {
+ return $this->record['id'];
+ }
+
+ public function getCategory() {
+ if (is_null($this->mainLib)) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ return $this->mainLib->call('getCategory', $this->record['category'], $this->user);
+ }
+
+ public function getOrder() {
+ return $this->record['f_order'];
+ }
+
+ public function getTitle() {
+ return $this->record['title'];
+ }
+
+ public function getDescription() {
+ return $this->record['description'];
+ }
+
+ public function isDeleted() {
+ return !is_null($this->record['deleted']);
+ }
+
+ public function deletedAt() {
+ return $this->isDeleted() ? $this->record['deleted'] : null;
+ }
+
+ public function deletedBy() {
+ return $this->isDeleted() ? $this->record['deleted_by'] : null;
+ }
+
+ public function getTopics() {
+ return $this->record['topics'];
+ }
+
+ public function getPosts() {
+ return $this->record['posts'];
+ }
+
+ public function getUnread() {
+ if (is_null($this->unread)) {
+ $q = self::$queries['getRead']->execute($this->record['id'], $this->user);
+ if (! ($q && dbCount($q) == 1)) {
+ return 0;
+ }
+ list($r) = dbFetchArray($q);
+ $this->unread = $this->record['topics'] - $r;
+ }
+ return $this->unread;
+ }
+
+ public function isAdmin() {
+ return $this->privs['adm'];
+ }
+
+ public function isMod() {
+ return $this->privs['mod'];
+ }
+
+ public function canCreateTopic() {
+ return $this->privs['ntop'];
+ }
+
+ public function canCreatePoll() {
+ return $this->privs['poll'];
+ }
+
+ public function canPost() {
+ return $this->privs['post'];
+ }
+
+ public function canView() {
+ return $this->privs['view'];
+ }
+
+ public function getLastPost() {
+ $q = $this->db->query("SELECT * FROM forums.get_last_post($1)", $this->record['id']);
+ if (! ($q && dbCount($q))) {
+ return null;
+ }
+
+ if (! $this->mainLib) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ return $this->mainLib->call('getPost', dbFetchHash($q), $this->user);
+ }
+
+ public function setParent( $category ) {
+ $this->parent = $category;
+ }
+
+ public function getParent() {
+ return $this->parent;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // FORUM'S ACCESS LIST
+ // ----------------------------------------------------------------------
+
+ private function getAcl($type, $libFunc, $iWantNames) {
+ // Check if we read that already
+ $aKey = $iWantNames ? 'names' : 'ids';
+ if (array_key_exists($aKey, $this->acl[$type])) {
+ return $this->acl[$type][$aKey];
+ }
+
+ // Get the library and extract the ACL IDs
+ $catLib = $this->getCategory()->getLibrary();
+ if (! array_key_exists('ids', $this->acl[$type])) {
+ $this->acl[$type]['ids'] = $catLib->call($libFunc, $this->record['id']);
+ }
+
+ // If we were requesting the IDs, leave
+ if ($aKey == 'ids') {
+ return $this->acl[$type]['ids'];
+ }
+
+ // If the IDs list is null, names are null as well
+ if (is_null($this->acl[$type]['ids'])) {
+ $this->acl[$type]['names'] = null;
+ return $this->acl[$type]['names'];
+ }
+
+ // Convert the identifiers to names and return
+ $this->acl[$type]['names'] = array();
+ foreach ($this->acl[$type]['ids'] as $id) {
+ $this->acl[$type]['names'][$id] = $catLib->call('aclIdToName', $id);
+ }
+ return $this->acl[$type]['names'];
+ }
+
+ public function getAdministrators($iWantNames = false) {
+ return $this->getAcl("admins", "getAdmins", $iWantNames);
+ }
+
+ public function getModerators($iWantNames = false) {
+ return $this->getAcl("mods", "getModerators", $iWantNames);
+ }
+
+ public function getUsers($iWantNames = false) {
+ return $this->getAcl("users", "getUsers", $iWantNames);
+ }
+
+ public function clearACL() {
+ $this->getCategory()->getLibrary()->call('clearForumACL', $this->record['id']);
+ $this->acl = array(
+ 'users' => array(),
+ 'mods' => array(),
+ 'admins' => array()
+ );
+ }
+
+ public function addModerator($id) {
+ $this->getCategory()->getLibrary()->call('addForumModerator', $this->record['id'], $id);
+ $this->acl['mods'] = array();
+ }
+
+ public function addUser($id) {
+ $this->getCategory()->getLibrary()->call('addForumUser', $this->record['id'], $id);
+ $this->acl['users'] = array();
+ }
+
+
+ // ----------------------------------------------------------------------
+ // SETTING FORUM PROPERTIES
+ // ----------------------------------------------------------------------
+
+ public function setAdmin($value) {
+ $this->privs['adm'] = $value;
+ }
+
+ public function setMod($value) {
+ $this->privs['mod'] = $value;
+ }
+
+ public function setCreateTopic($value) {
+ $this->privs['ntop'] = $value;
+ }
+
+ public function setCreatePoll($value) {
+ $this->privs['poll'] = $value;
+ }
+
+ public function setPost($value) {
+ $this->privs['post'] = $value;
+ }
+
+ public function setView($value) {
+ $this->privs['view'] = $value;
+ }
+
+ public function increaseOrder() {
+ $this->record['f_order'] ++;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // INTERNAL METHODS FOR CHECKS AND FORMATTING
+ // ----------------------------------------------------------------------
+
+ private function checkPostContents($title, $contents) {
+ if (strlen($title) < 2) {
+ $e = 1;
+ } elseif (strlen($title) > 100) {
+ $e = 2;
+ } elseif (strlen($contents) < 3) {
+ $e = 3;
+ } else {
+ $e = 0;
+ }
+ return $e;
+ }
+
+
+ private function reformatContents($contents) {
+ // Max. line breaks
+ $maxNL = 500;
+ // Max. characters without break
+ $maxNC = 100;
+
+ $ot = $contents;
+ $nt = "";
+ $nl = 0;
+
+ while ($ot != '' && $nl < $maxNL) {
+ $p = strpos($ot, '\n');
+ if ($p !== false && $p < $maxNC) {
+ $nt .= substr($ot, 0, $p+1);
+ $ot = substr($ot, $p+1);
+ } else if (strlen($ot) < $maxNC) {
+ $nt .= $ot;
+ $ot = "";
+ } else {
+ $s = substr($ot, 0, $maxNC);
+ $p = strrpos($s, ' ');
+ $ot = substr($ot, $maxNC);
+ $nt .= $s;
+ if ($p === false) {
+ $nt .= "\n";
+ }
+ }
+ $nl ++;
+ }
+
+ if ($nl >= $maxNL) {
+ return null;
+ }
+ return $nt;
+ }
+
+
+
+ // ----------------------------------------------------------------------
+ // OPERATIONS
+ // ----------------------------------------------------------------------
+
+ /* This method creates a new topic in the forum. It returns the
+ * corresponding fl_topic instance or a numeric error code.
+ *
+ * Error codes:
+ * -1 - Permission denied (topic creation)
+ * -2 - Permission denied (poll creation)
+ * -3 - Title too short
+ * -4 - Title too long
+ * -5 - Contents too short
+ * -6 - Contents too long
+ * -7 - Permission denied (sticky)
+ * -8 - Database access error
+ * -9 - Poll title too short
+ * -10 - Poll title too long
+ * -11 - Not enough poll options
+ * -12 - Too many poll options
+ */
+ public function createTopic(
+ $title, $contents, $stickyLevel,
+ $enableCode, $enableSmileys, $enableSignature,
+ $poll = null
+ ) {
+ // Check posting privileges
+ if ( ! $this->canCreateTopic() ) {
+ return -1;
+ }
+ if ( ! (is_null($poll) || $this->canCreatePoll()) ) {
+ return -2;
+ }
+
+ // Check the title and contents
+ $title = trim($title);
+ $contents = trim($contents);
+ $pc = $this->checkPostContents($title, $contents);
+ if ($pc) {
+ return - $pc - 2;
+ }
+
+ // Reformat the post's contents
+ $contents = $this->reformatContents($contents);
+ if (is_null($contents)) {
+ return -6;
+ }
+
+ // Check the sticky level
+ $stickyLevel = (int) $stickyLevel;
+ if ( $stickyLevel < 0 || $stickyLevel > 10 || ($stickyLevel > 0 && ! $this->isMod()) ) {
+ return -7;
+ }
+
+ // Check the poll's contents
+ if (! is_null($poll)) {
+ $pc = $poll->checkData();
+ if ($pc != 0) {
+ return - $pc - 8;
+ }
+ }
+
+ // Get the user's current signature if needed
+ if ($enableSignature) {
+ $q = self::$queries['getCurrentSig']->execute($this->user);
+ if ( ! ($q && dbCount($q)) ) {
+ return -8;
+ }
+
+ list($sig) = dbFetchArray($q);
+ } else {
+ $sig = null;
+ }
+
+ // Add the topic
+ $q = self::$queries['createTopic']->execute(array(
+ "forum" => $this->record['id'],
+ "user" => $this->user,
+ "sticky" => $stickyLevel,
+ "title" => $title,
+ "contents" => $contents,
+ "code" => dbBool($enableCode),
+ "smileys" => dbBool($enableSmileys),
+ "sig" => $sig
+ ));
+ if (! ($q && dbCount($q)) ) {
+ return -8;
+ }
+ list($tid) = dbFetchArray($q);
+ if (is_null($tid)) {
+ return -8;
+ }
+
+ // Insert poll if needed
+ if (! (is_null($poll) || $poll->insertIntoDB( $this->game, $this->user, $tid ) ) ) {
+ self::$queries['killTopic']->execute($tid);
+ return -8;
+ }
+
+ if (! $this->mainLib) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ $topic = $this->mainLib->call('getTopic', $tid, $this->user);
+
+ $this->refresh();
+ return $topic;
+ }
+
+
+ public function getTopicList() {
+ if (is_null($this->topicList)) {
+ $q = self::$queries['getTopics']->execute($this->record['id']);
+ if (! $q) {
+ return null;
+ }
+
+ if (is_null($this->mainLib)) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ $this->topicList = array();
+ while ($r = dbFetchHash($q)) {
+ $t = $this->mainLib->call('getTopic', $r, $this->user);
+ $this->topicList[$t->getId()] = $t;
+ }
+ }
+
+ return $this->topicList;
+ }
+
+ public function findTopic( $id ) {
+ if (is_null($this->topicList)) {
+ $this->getTopicList();
+ }
+ return array_key_exists($id, $this->topicList) ? $this->topicList[$id] : null;
+ }
+
+ /* Deletes the forum */
+ function delete() {
+ if ($this->isDeleted()) {
+ return;
+ }
+
+ $this->db->query("SELECT forums.delete_forum($1, $2)", $this->record['id'], $this->user);
+
+ $q = self::$queries['getInfo']->execute($this->record['id']);
+ if ($q && dbCount($q) == 1) {
+ $this->record = dbFetchHash($q);
+ }
+ }
+
+ /* Restore the forum */
+ function restore() {
+ if (!$this->isDeleted()) {
+ return;
+ }
+
+ $this->db->query("SELECT forums.restore_forum($1)", $this->record['id']);
+
+ $q = self::$queries['getInfo']->execute($this->record['id']);
+ if ($q && dbCount($q) == 1) {
+ $this->record = dbFetchHash($q);
+ }
+ }
+
+ /* Moves the forum either up or down */
+ function move($moveUp) {
+ $rv = $this->getCategory()->moveForum($this->record['id'], $moveUp);
+ if ($rv !== false) {
+ $this->record['f_order'] += ($moveUp ? -1 : 1);
+ $rv->record['f_order'] += ($moveUp ? 1 : -1);
+ }
+ }
+
+ /* Mark all topics as read */
+ function markRead() {
+ $this->db->query("SELECT forums.mark_forum_read($1, $2)", $this->record['id'], $this->user);
+ }
+
+ /* Forces the object to be re-read from the DB */
+ function refresh() {
+ $q = self::$queries['getInfo']->execute($this->record['id']);
+ if (! ($q && dbCount($q) == 1)) {
+ return;
+ }
+ $this->record = dbFetchHash($q);
+ $this->unread = $this->topics = $this->topicList = null;
+
+ if ($this->parent) {
+ $this->parent->refresh();
+ }
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/main/forums/fl_poll.inc forums//scripts/game/main/forums/fl_poll.inc
--- beta5//scripts/game/main/forums/fl_poll.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/forums/fl_poll.inc 2011-02-05 10:10:03.434335002 +0100
@@ -0,0 +1,373 @@
+fromDB = false;
+ $this->checked = false;
+ $this->record = array(
+ 'title' => preg_replace('/\s+/', ' ', trim($args[0]))
+ );
+ } else {
+ // Load from database
+ $this->fromDB = true;
+ $this->checked = true;
+ $this->game = $args[0];
+ $this->db = $this->game->getDBAccess();
+ $this->mainLib = $this->game->getLib('main/forums');
+ $this->user = $args[1];
+ $id = $args[2];
+
+ // Fetch the poll's data
+ $q = $this->db->query("SELECT * FROM forums.poll WHERE topic = $1 FOR UPDATE", $id);
+ if (! ($q && dbCount($q) == 1)) {
+ throw new Exception("No poll found for topic #$id");
+ }
+ $this->record = dbFetchHash($q);
+
+ // Fetch the poll options
+ $q = $this->db->query("SELECT * FROM forums.poll_option "
+ . "WHERE poll = $1 ORDER BY po_order "
+ . "FOR UPDATE", $id);
+ if (! ($q && dbCount($q) > 1)) {
+ throw new Exception("Poll options not found for topic #$id");
+ }
+ while ($r = dbFetchHash($q)) {
+ array_push($this->options, $r);
+ }
+
+ $this->prepareNbVotesQuery();
+ }
+ }
+
+
+ private function prepareNbVotesQuery() {
+ $this->nbVotesQ = $this->db->prepare(
+ "SELECT COUNT(*) FROM forums.poll_vote WHERE vote = $1", array("option") );
+ }
+
+
+ // ----------------------------------------------------------------------
+ // READING POLL PROPERTIES
+ // ----------------------------------------------------------------------
+
+ public function getTopic() {
+ if (! $this->fromDB) {
+ return null;
+ }
+ return $this->mainLib->call('getTopic', $this->record['topic'] );
+ }
+
+ public function getTitle() {
+ return $this->record['title'];
+ }
+
+ public function isClosed() {
+ return $this->fromDB && ($this->record['closed'] == 't');
+ }
+
+ public function isDeleted() {
+ return $this->fromDB && !is_null($this->record['deleted']);
+ }
+
+ public function getDeletionTime() {
+ return $this->fromDB ? $this->record['deleted'] : null;
+ }
+
+ public function getDeletionMod() {
+ return $this->fromDB ? $this->record['deleted_by'] : null;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // POLL CREATION
+ // ----------------------------------------------------------------------
+
+ /* Checks the poll's data before inserting it in the database.
+ * Returns null if the poll is already inside the database, 0 if the poll
+ * is ok, or one of the following error codes:
+ * 1 - Title too short
+ * 2 - Title too long
+ * 3 - Not enough options
+ * 4 - Too many options
+ */
+ public function checkData() {
+ if ($this->fromDB || $this->checked) {
+ return null;
+ }
+
+ $l = strlen($this->record['title']);
+ if ($l < 3) {
+ return 1;
+ } elseif ($l > 64) {
+ return 2;
+ }
+
+ $c = count($this->options);
+ if ($c < 2) {
+ return 3;
+ } elseif ($c > 20) {
+ return 4;
+ }
+
+ $this->checked = true;
+ return 0;
+ }
+
+ /* Insert the poll's data into the database. */
+ public function insertIntoDB($game, $user, $topicId) {
+ if ($this->fromDB || ! $this->checked) {
+ return false;
+ }
+ $db = $game->getDBAccess();
+
+ // Insert the poll
+ $q = $db->query("SELECT * FROM forums.create_poll($1, $2)", $topicId, $this->record['title']);
+ if (! ($q && dbCount($q) == 1)) {
+ return false;
+ }
+
+ $rec = dbFetchHash($q);
+ if (is_null($rec['topic'])) {
+ return false;
+ }
+
+ // Insert the options
+ $pollQuery = $db->prepare("SELECT * FROM forums.create_option($1, $2, $3)",
+ array("poll", "order", "title") );
+ try {
+ $nOpts = array();
+ for ($i = 0; $i < count($this->options); $i ++) {
+ $q = $pollQuery->execute(array(
+ "poll" => $topicId,
+ "order" => $i,
+ "title" => $this->options[$i]['title']
+ ));
+ if (! ($q && dbCount($q) == 1)) {
+ throw new Exception('abort');
+ }
+
+ $orec = dbFetchHash($q);
+ if (is_null($orec['id'])) {
+ throw new Exception('abort');
+ }
+
+ array_push($nOpts, $orec);
+ }
+ $pollQuery->destroy();
+ } catch (Exception $e) {
+ $pollQuery->destroy();
+ $db->query("DELETE FROM forums.poll WHERE topic = $1", $topicId);
+ return false;
+ }
+
+ // Finalize
+ $this->record = $rec;
+ $this->options = $nOpts;
+ $this->game = $game;
+ $this->db = $db;
+ $this->user = $user;
+ $this->mainLib = $this->game->getLib('main/forums');
+ $this->prepareNbVotesQuery();
+ $this->fromDB = true;
+ return true;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // OPTIONS
+ // ----------------------------------------------------------------------
+
+ /* Adds a new option at the end of the list.
+ * Returns 0 on success or one of the following error codes:
+ * -1 - Title too short
+ * -2 - Title too long
+ * -3 - Too many options
+ * -4 - Database error
+ * -5 - Adding options after the poll has been checked is not permitted
+ */
+ public function appendOption($title) {
+ $title = preg_replace('/\s+/', ' ', trim($title));
+ $l = strlen($title);
+ if ($l < 2) {
+ return -1;
+ } elseif ($l > 64) {
+ return -2;
+ }
+
+ if ($this->fromDB) {
+ $c = count($this->options);
+ if ($c == 20) {
+ return -3;
+ }
+
+ $q = $this->db->query("SELECT * FROM forums.create_option($1, $2, $3)",
+ $this->record['topic'], $c, $title);
+ if (! ($q && dbCount($q) == 1)) {
+ return -4;
+ }
+ array_push($this->options, dbFetchHash($q));
+ } else if (!$this->checked) {
+ array_push($this->options, array(
+ 'title' => $title
+ ));
+ } else {
+ return -5;
+ }
+ return 0;
+ }
+
+ /* Removes the poll option with the specified index. */
+ public function removeOption( $order ) {
+ $order = (int) $order;
+ if ($order < 0 || $order >= count($this->options)) {
+ return false;
+ }
+
+ if ($this->fromDB) {
+ $q = $this->db->query("SELECT forums.delete_option( $1, $2 )", $this->record['topic'], $order);
+ if (! ($q && dbCount($q) == 1)) {
+ return false;
+ }
+ list($ok) = dbFetchArray($q);
+ if ($ok != 't') {
+ return false;
+ }
+
+ for ($i = $order + 1; $i < count($this->options); $i ++) {
+ $this->options[$i]['po_order'] --;
+ }
+ }
+ array_splice($this->options, $order, 1);
+ return true;
+ }
+
+ /* Get the options */
+ public function getOptions() {
+ $opts = $this->options;
+ if (! $this->fromDB) {
+ for ($i = 0; $i < count($opts); $i++) {
+ $opts[$i]['po_order'] = $i;
+ }
+ }
+ return $opts;
+ }
+
+ /* Move an option up in the list of options */
+ public function moveUp( $order ) {
+ if ($order <= 0 || $order >= count($this->options)) {
+ return false;
+ }
+
+ if ($this->fromDB) {
+ $q = $this->db->query("SELECT forums.move_opt_up( $1, $2 )", $this->record['topic'], $order);
+ if (! ($q && dbCount($q) == 1)) {
+ return false;
+ }
+ list($ok) = dbFetchArray($q);
+ if ($ok != 't') {
+ return false;
+ }
+
+ $this->options[$order]['po_order'] --;
+ $this->options[$order - 1]['po_order'] ++;
+ }
+
+ $tmp = $this->options[$order];
+ $this->options[$order] = $this->options[$order - 1];
+ $this->options[$order - 1] = $tmp;
+ return true;
+ }
+
+ /* Move an option down in the list of options */
+ public function moveDown( $order ) {
+ if ($order < 0 || $order >= count($this->options) - 1) {
+ return false;
+ }
+
+ if ($this->fromDB) {
+ $q = $this->db->query("SELECT forums.move_opt_down($1,$2)", $this->record['topic'], $order);
+ if (! ($q && dbCount($q) == 1)) {
+ return false;
+ }
+ list($ok) = dbFetchArray($q);
+ if ($ok != 't') {
+ return false;
+ }
+
+ $this->options[$order]['po_order'] ++;
+ $this->options[$order + 1]['po_order'] --;
+ }
+
+ $tmp = $this->options[$order];
+ $this->options[$order] = $this->options[$order + 1];
+ $this->options[$order + 1] = $tmp;
+ return true;
+ }
+
+ /* Vote */
+ public function setVote( $order ) {
+ if (! $this->fromDB || $order < 0 || $order >= count($this->options)) {
+ return false;
+ }
+
+ $q = $this->db->query("SELECT forums.set_vote($1,$2,$3)", $this->user, $this->record['topic'],
+ $this->options[$order]['id']);
+ if (! $q) {
+ return false;
+ }
+ return true;
+ }
+
+ /* Returns the order of the option the user is voting for */
+ public function getVote() {
+ if (! $this->fromDB) {
+ return null;
+ }
+
+ $q = $this->db->query("SELECT o.po_order FROM forums.poll_option o, forums.poll_vote v "
+ . " WHERE o.id = v.vote AND o.poll = $1 AND v.account = $2",
+ $this->record['topic'], $this->user);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($order) = dbFetchArray($q);
+ return $order;
+ }
+
+ /* Returns the amount of votes for an option */
+ public function getNbVotes( $order ) {
+ if (! $this->fromDB || $order < 0 || $order >= count($this->options)) {
+ return 0;
+ }
+
+ $q = $this->nbVotesQ->execute($this->options[$order]['id']);
+ if (!($q && dbCount($q) == 1)) {
+ return 0;
+ }
+
+ list($votes) = dbFetchArray($q);
+ return $votes;
+ }
+}
+
+
+?>
diff -Naur beta5//scripts/game/main/forums/fl_post.inc forums//scripts/game/main/forums/fl_post.inc
--- beta5//scripts/game/main/forums/fl_post.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/forums/fl_post.inc 2011-02-05 10:10:03.434335002 +0100
@@ -0,0 +1,219 @@
+game = $game;
+ $this->user = $user;
+ $this->db = $this->game->getDBAccess();
+ $this->mainLib = $this->game->getLib('main/forums');
+
+ if (is_array($data)) {
+ $this->record = $data;
+ } else {
+ $data = (int) $data;
+ $row = self::$getQ->execute($data);
+ if (! ($row && dbCount($row) == 1)) {
+ throw new Exception("Post #$data not found");
+ }
+ $this->record = dbFetchHash($row);
+ }
+ }
+
+
+ static private function initQueries() {
+ if (! is_null(self::$getQ)) {
+ return;
+ }
+
+ $db = config::getMainInterface()->getDBAccess();
+ self::$getQ = $db->prepare( "SELECT * FROM forums.post WHERE id = $1", array("id") );
+ self::$historyQ = $db->prepare( "SELECT * FROM forums.post_text WHERE post = $1 ORDER BY moment",
+ array( "post" ));
+ self::$repliesQ = $db->prepare( "SELECT id FROM forums.post WHERE reply_to = $1 ORDER BY post_moment",
+ array( "post" ));
+ }
+
+
+ // ----------------------------------------------------------------------
+ // READING POST PROPERTIES
+ // ----------------------------------------------------------------------
+
+ public function getId() {
+ return $this->record['id'];
+ }
+
+
+ public function getForum() {
+ return $this->mainLib->call('getForum', $this->record['forum'], $this->user);
+ }
+
+ public function getTopic() {
+ return $this->mainLib->call('getTopic', $this->record['topic'], $this->user);
+ }
+
+
+ public function getParent() {
+ return is_null($this->record['reply_to']) ? null
+ : $this->mainLib->call('getPost', $this->record['reply_to'], $this->user);
+ }
+
+ public function getDepth() {
+ return $this->record['depth'];
+ }
+
+
+ public function getPostedAt() {
+ return $this->record['post_moment'];
+ }
+
+ public function getPostedBy() {
+ return $this->record['author'];
+ }
+
+ public function getLastChange() {
+ return $this->record['last_change'];
+ }
+
+ public function getLastChangeAuthor() {
+ return $this->record['last_author'];
+ }
+
+ public function isUnread() {
+ $topic = $this->getTopic();
+ if (is_null($topic)) {
+ return false;
+ }
+
+ return $topic->getLastRead() < $this->record['last_change'];
+ }
+
+
+ public function isDeleted() {
+ return ! is_null($this->record['deleted']);
+ }
+
+ public function getDeletionTime() {
+ return $this->record['deleted'];
+ }
+
+ public function getDeletionMod() {
+ return $this->record['deleted_by'];
+ }
+
+
+ public function getTitle() {
+ return $this->record['title'];
+ }
+
+ public function getContents($time = null) {
+ if (is_null($time)) {
+ $v = $this->record['contents'];
+ } else {
+ $hist = $this->getFullHistory();
+ $v = '';
+ foreach ($hist as $he) {
+ if ($he['moment'] > $time) {
+ break;
+ }
+ $v = $he['contents'];
+ }
+ }
+ return $v;
+ }
+
+ public function codeEnabled($time = null) {
+ if (is_null($time)) {
+ $v = $this->record['enable_code'];
+ } else {
+ $hist = $this->getFullHistory();
+ $v = false;
+ foreach ($hist as $he) {
+ if ($he['moment'] > $time) {
+ break;
+ }
+ $v = $he['enable_code'];
+ }
+ }
+ return ($v == 't');
+ }
+
+ public function smileysEnabled($time = null) {
+ if (is_null($time)) {
+ $v = $this->record['enable_smileys'];
+ } else {
+ $hist = $this->getFullHistory();
+ $v = false;
+ foreach ($hist as $he) {
+ if ($he['moment'] > $time) {
+ break;
+ }
+ $v = $he['enable_smileys'];
+ }
+ }
+ return ($v == 't');
+ }
+
+
+ public function getSignature() {
+ throw new Exception("FIXME: getSignature() is not implemented");
+ }
+
+ /* This function returns a post's full history */
+ public function getFullHistory() {
+ if (is_null( $this->history )) {
+ $result = self::$historyQ->execute($this->record['id']);
+ if (! ($result && dbCount($result))) {
+ return null;
+ }
+ $history = array();
+ while ($row = dbFetchHash($result)) {
+ array_push($history, $row);
+ }
+ $this->history = $history;
+ }
+ return $this->history;
+ }
+
+ /* This function returns the replies to a post */
+ public function getReplies() {
+ if (is_null( $this->replies )) {
+ $result = self::$repliesQ->execute($this->record['id']);
+ if (! $result) {
+ return null;
+ }
+ $this->replies = array();
+ while ($row = dbFetchArray($result)) {
+ $reply = $this->mainLib->call('getPost', $row[0], $this->user);
+ if (! is_null($reply)) {
+ array_push($this->replies, $reply);
+ }
+ }
+ }
+ return $this->replies;
+ }
+
+ /* This function deletes a post if it is not the top-level post */
+ public function delete() {
+ }
+}
+
+
+?>
diff -Naur beta5//scripts/game/main/forums/fl_topic.inc forums//scripts/game/main/forums/fl_topic.inc
--- beta5//scripts/game/main/forums/fl_topic.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/forums/fl_topic.inc 2011-02-05 10:10:03.434335002 +0100
@@ -0,0 +1,339 @@
+game = $game;
+ $this->db = $this->game->getDBAccess();
+ $this->user = $user;
+
+ if (is_array($data)) {
+ $this->record = $data;
+ } else {
+ $data = (int) $data;
+ $q = self::$getQuery->execute($data);
+ if (! ($q && dbCount($q) == 1)) {
+ throw new Exception("Topic #$data not found");
+ }
+ $this->record = dbFetchHash($q);
+ }
+ }
+
+ static private function initQueries() {
+ if (is_null(self::$getQuery)) {
+ $db = config::getMainInterface()->getDBAccess();
+ self::$getQuery = $db->prepare(
+ "SELECT * FROM forums.topic WHERE id = $1",
+ array("id") );
+ self::$restoreQuery = $db->prepare( "SELECT forums.restore_post( $1 )", array("id") );
+ self::$deleteQuery = $db->prepare( "SELECT forums.delete_post( $1 , $2 )",
+ array("id", "user") );
+ self::$stickyLevelQuery = $db->prepare( "UPDATE forums.t_topic SET sticky_level = $2 "
+ . "WHERE id = $1", array("id", "level") );
+ self::$setLockQuery = $db->prepare( "UPDATE forums.t_topic SET locked = $2 WHERE id = $1",
+ array("id", "locked") );
+ self::$moveQuery = $db->prepare( "SELECT forums.move_topic( $1, $2, $3)",
+ array("topic", "destination", "user") );
+ self::$postsQuery = $db->prepare( "SELECT * FROM forums.post WHERE topic = $1",
+ array("topic") );
+ }
+ }
+
+
+ // ----------------------------------------------------------------------
+ // READING TOPIC PROPERTIES
+ // ----------------------------------------------------------------------
+
+ public function getId() {
+ return $this->record['id'];
+ }
+
+ public function getForum() {
+ if (is_null($this->mainLib)) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ return $this->mainLib->call('getForum', $this->record['forum'], $this->user);
+ }
+
+ public function getMovedFrom() {
+ if (is_null($this->record['moved_from'])) {
+ return null;
+ }
+
+ if (is_null($this->mainLib)) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ return $this->mainLib->call('getForum', $this->record['moved_from'], $this->user);
+ }
+
+ public function isInForum($forum) {
+ return ($forum->getId() == $this->record['forum']);
+ }
+
+ public function getPoll() {
+ if (is_null($this->mainLib)) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ return $this->mainLib->call('getPoll', $this->record['id'], $this->user);
+ }
+
+ public function getStickyLevel() {
+ return $this->record['sticky_level'];
+ }
+
+ public function getTitle() {
+ return $this->record['title'];
+ }
+
+ public function getPosted() {
+ return $this->record['fp_moment'];
+ }
+
+ public function getAuthor() {
+ return $this->record['fp_author'];
+ }
+
+ public function getLastChange() {
+ return $this->record['lc_moment'];
+ }
+
+ public function getLastChangeAuthor() {
+ return $this->record['lc_author'];
+ }
+
+ public function isDeleted() {
+ return ! is_null($this->record['deleted']);
+ }
+
+ public function getDeletionTime() {
+ return $this->record['deleted'];
+ }
+
+ public function getDeletionMod() {
+ return $this->record['deleted_by'];
+ }
+
+ public function isLocked() {
+ return ($this->record['locked'] == 't');
+ }
+
+ public function getLastRead() {
+ if (is_null($this->lastRead)) {
+ $q = $this->db->query("SELECT read_at FROM forums.topic_read WHERE topic = $1 AND read_by = $2",
+ $this->record['id'], $this->user);
+ if (!($q && dbCount($q) == 1)) {
+ return 0;
+ }
+
+ list($this->lastRead) = dbFetchArray($q);
+ }
+
+ return $this->lastRead;
+ }
+
+
+ // ----------------------------------------------------------------------
+ // MANAGEMENT FUNCTIONS
+ // ----------------------------------------------------------------------
+
+ public function restore() {
+ if (! $this->isDeleted() ) {
+ return;
+ }
+ self::$restoreQuery->execute( $this->record['first_post'] );
+ $q = self::$getQuery->execute( $this->record['id'] );
+ if (! ($q && dbCount($q))) {
+ return;
+ }
+ $this->record = dbFetchHash($q);
+ }
+
+ public function delete() {
+ if ($this->isDeleted() ) {
+ return;
+ }
+ self::$deleteQuery->execute( $this->record['first_post'], $this->user );
+ $q = self::$getQuery->execute( $this->record['id'] );
+ if (! ($q && dbCount($q))) {
+ return;
+ }
+ $this->record = dbFetchHash($q);
+ }
+
+ public function setStickyLevel( $level ) {
+ if ($this->isDeleted() ) {
+ return;
+ }
+ if ($level < 0 || $level > 10) {
+ return;
+ }
+ self::$stickyLevelQuery->execute( $this->record['id'], $level );
+ $this->record['sticky_level'] = $level;
+ }
+
+ public function setLock( $locked ) {
+ if ($this->isDeleted() ) {
+ return;
+ }
+ self::$setLockQuery->execute( $this->record['id'], dbBool($locked) );
+ $this->record['locked'] = $locked ? 't' : 'f';
+ }
+
+ public function moveTo( $forum ) {
+ if ($this->isDeleted() ) {
+ return;
+ }
+ self::$moveQuery->execute($this->record['id'], $forum->getId(), $this->user);
+ $q = self::$getQuery->execute( $this->record['id'] );
+ if (! ($q && dbCount($q))) {
+ return;
+ }
+ $this->record = dbFetchHash($q);
+ }
+
+
+ // ----------------------------------------------------------------------
+ // ACCESSING THE POSTS
+ // ----------------------------------------------------------------------
+
+ public function getPosts() {
+ return $this->record['posts'];
+ }
+
+ public function getFirstPost() {
+ if (is_null($this->mainLib)) {
+ $this->mainLib = $this->game->getLib('main/forums');
+ }
+ return $this->mainLib->call('getPost', $this->record['first_post'], $this->user);
+ }
+
+ private function loadPosts() {
+ if (is_null($this->allPosts)) {
+ $q = self::$postsQuery->execute($this->record['id']);
+ if (! ($q && dbCount($q))) {
+ return null;
+ }
+
+ $this->allPosts = array();
+ while ($r = dbFetchHash($q)) {
+ $this->allPosts[$r['id']] = $this->mainLib->call('getPost', $r, $this->user);
+ }
+ }
+ }
+
+ public function getPostList($isThreaded, $oldFirst) {
+ $this->loadPosts();
+
+ if ($isThreaded) {
+ $result = $this->threadedSort($this->getFirstPost()->getReplies(), $oldFirst);
+ if (count($result)) {
+ array_shift($result);
+ }
+ array_unshift($result, $this->getFirstPost());
+ } else {
+ // If we are not in threaded mode, generate the list
+ // of reverse post <=> time associations and sort it
+ // in the appropriate direction
+ $timeList = array();
+ $result = array();
+
+ foreach ($this->allPosts as $id => $p) {
+ $time = (int) $p->getPostedAt();
+ if (! is_array($timeList[$time])) {
+ $timeList[$time] = array();
+ }
+ array_push($timeList[$time], $p);
+ }
+
+ $times = array_keys($timeList);
+ if ($oldFirst) {
+ sort($times);
+ } else {
+ rsort($times);
+ }
+
+ foreach ($times as $t) {
+ foreach ($timeList[$t] as $p) {
+ array_push($result, $p);
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ private function threadedSort($posts, $oldFirst) {
+ if (! count($posts)) {
+ return array();
+ }
+
+ $timeList = array();
+ $replyList = array();
+
+ foreach ($posts as $post) {
+ $postReplies = $this->threadedSort($post->getReplies(), $oldFirst);
+
+ if (count($postReplies)) {
+ $time = array_shift($postReplies);
+ $replyList[$post->getId()] = $postReplies;
+ } else {
+ $time = $post->getPostedAt();
+ $replyList[$post->getId()] = array();
+ }
+
+ $time = (int) $time;
+ if (! is_array($timeList[$time])) {
+ $timeList[$time] = array();
+ }
+ array_push($timeList[$time], $post);
+ }
+
+ $times = array_keys($timeList);
+ if ($oldFirst) {
+ sort($times);
+ } else {
+ rsort($times);
+ }
+
+ $result = array($times[0]);
+ foreach ($times as $t) {
+ foreach ($timeList[$t] as $p) {
+ array_push($result, $p);
+ foreach ($replyList[$p->getId()] as $r) {
+ array_push($result, $r);
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ public function getPostById($id) {
+ $this->loadPosts();
+ return array_key_exists($id, $this->allPosts) ? $this->allPosts[$id] : null;
+ }
+}
+
+
+?>
diff -Naur beta5//scripts/game/main/forums/library/substitute.inc forums//scripts/game/main/forums/library/substitute.inc
--- beta5//scripts/game/main/forums/library/substitute.inc 2011-02-05 10:09:57.844335002 +0100
+++ forums//scripts/game/main/forums/library/substitute.inc 2011-02-05 10:10:03.424335002 +0100
@@ -1,59 +1,73 @@
'\[b\](.*?)\[\/b\]',
+ "rt" => '$1 '
+ ), array(
+ "re" => '\[u\](.*?)\[\/u\]',
+ "rt" => '$1 '
+ ), array(
+ "re" => '\[i\](.*?)\[\/i\]',
+ "rt" => '$1 '
+ ), array(
+ "re" => '\[sep(arator)?\]',
+ "rt" => '
'
+ ), array(
+ "re" => '\[item\](.*?)\[\/item\]',
+ "rt" => ''
+ ), array(
+ "re" => '\[quote\](.*?)\[\/quote\]',
+ "rt" => '$1 ',
+ "rep" => true
+ ), array(
+ "re" => '\[quote=([^\]]+)\](.*?)\[\/quote\]',
+ "rt" => '$1 said: $2 ',
+ "rep" => true
+ ), array(
+ "re" => '\[link=(http[^\]]+)\](.+?)\[\/link\]',
+ "rt" => '$2 '
+ ), array(
+ "re" => '\[code\](.*?)\[\/code\]',
+ "rt" => '$1 '
+ )
+ );
function main_forums_substitute($lib) {
$this->lib = $lib;
$this->db = $this->lib->game->db;
}
- function run($text, $ec, $es) {
+ function run($text, $ec) {
$src = array('/\\n/','/\\r/'); $dst = array(" ",'');
+ $rsSrc = array(); $rsDst = array();
$text = utf8entities($text, ENT_NOQUOTES);
- $ec = ($ec == 't');
- $es = ($es == 't');
if ($ec) {
- if (is_array($this->code)) {
- foreach ($this->code as $s => $d) {
- array_push($src, '/'.$s.'/i');
- array_push($dst, $d);
- }
- } else {
- $this->codes = array();
- $q = $this->db->query("SELECT * FROM f_code");
- while ($r = dbFetchArray($q)) {
- $this->code[$r[0]] = $r[1];
- array_push($src, '/'.$r[0].'/i');
- array_push($dst, $r[1]);
+ foreach (self::$code as $c) {
+ if ($c['rep']) {
+ array_push($rsSrc, "/{$c['re']}/i");
+ array_push($rsDst, $c['rt']);
+ } else {
+ array_push($src, "/{$c['re']}/i");
+ array_push($dst, $c['rt']);
}
}
}
- if ($es) {
- if (is_array($this->smiley)) {
- foreach ($this->smiley as $s => $d) {
- array_push($src, '/'.$s.'/i');
- array_push($dst, $d);
- }
- } else {
- $this->smiley = array();
- $q = $this->db->query("SELECT * FROM f_smiley");
- while ($r = dbFetchArray($q)) {
- $fn = getStatic("main/pics/smiles/icon_".$r[1].".gif");
- if (is_null($fn)) {
- continue;
- }
- $code = " ";
- $this->smiley[$r[0]] = $code;
- array_push($src, '/'.$r[0].'/i');
- array_push($dst, $code);
+
+ if (count($rsSrc)) {
+ $i = 0;
+ foreach ($rsSrc as $re) {
+ while (preg_match($re, $text)) {
+ $text = preg_replace($re, $rsDst[$i], $text);
}
+ $i ++;
}
}
- return preg_replace($src, $dst, $text);
+ $rv = preg_replace($src, $dst, $text);
+ return $rv;
}
}
diff -Naur beta5//scripts/game/main/forums/library.inc forums//scripts/game/main/forums/library.inc
--- beta5//scripts/game/main/forums/library.inc 2011-02-05 10:09:57.844335002 +0100
+++ forums//scripts/game/main/forums/library.inc 2011-02-05 10:10:03.434335002 +0100
@@ -1,71 +1,152 @@
lib = $lib;
- $this->db = $this->lib->game->db;
- }
+ $this->game = $this->lib->game;
+ $this->db = $this->game->getDBAccess();
- function getVersionCategory($ver) {
- $q = $this->db->query("SELECT id,description FROM f_category WHERE title='!$ver!'");
- return dbFetchHash($q);
- }
+ $this->getForumLib = $this->db->prepare(
+ "SELECT l.lib_path FROM forums.t_forum f, forums.category c, forums.category_type l "
+ . "WHERE f.id = $1 AND c.id = f.category AND l.id = c.acl_lib",
+ array("id") );
+ $this->getCategoryLib = $this->db->prepare(
+ "SELECT l.lib_path FROM forums.category c, forums.category_type l "
+ . "WHERE l.id = c.acl_lib AND c.id = $1",
+ array("id") );
+ }
+
+ public function getCategory($id, $user) {
+ $idx = "$id;$user";
+
+ if (! isset($this->categories[$idx])) {
+ $q = $this->getCategoryLib->execute(array("id" => $id));
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($lib) = dbFetchArray($q);
+
+ if (! isset($this->libraries[$lib]) ) {
+ $this->libraries[$lib] = $this->game->getLib($lib);
+ }
+ $cat = $this->libraries[$lib]->call('getCategory', $id, $user);
+
+ if (is_null($cat)) {
+ return null;
+ }
+ $this->categories[$idx] = $cat;
+ }
- function isRead($topic, $player) {
- $q = $this->db->query("SELECT * FROM f_read WHERE topic=$topic AND reader=$player");
- return $q && dbCount($q);
+ return $this->categories[$idx];
}
- function markRead($topic, $player) {
- if ($this->isRead($topic,$player)) {
- return false;
+ public function getForum($id, $user) {
+ $idx = "$id;$user";
+
+ if (! isset($this->forums[$idx])) {
+ $q = $this->getForumLib->execute(array("id" => $id));
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($lib) = dbFetchArray($q);
+
+ if (! isset($this->libraries[$lib]) ) {
+ $this->libraries[$lib] = $this->game->getLib($lib);
+ }
+ $f = $this->libraries[$lib]->call('getForum', $id, $user);
+
+ if (is_null($f)) {
+ return null;
+ }
+ $this->forums[$idx] = $f;
}
- $this->db->query("DELETE FROM f_read WHERE topic=$topic AND reader=$player");
- $this->db->query("INSERT INTO f_read(topic,reader)VALUES($topic,$player)");
- return true;
+
+ return $this->forums[$idx];
}
- function markUnread($topic, $player) {
- $this->db->query("DELETE FROM f_read WHERE topic=$topic AND reader<>$player");
+ public function getTopic($data, $user) {
+ if (is_array($data)) {
+ $id = $data['id'];
+ } else {
+ $id = $data;
+ }
+ $idx = "$id;$user";
+
+ if (! isset($this->topics[$idx])) {
+ loader::needClasses('main/forums', 'fl_topic');
+ try {
+ $topic = new fl_topic($this->game, $user, $data);
+ } catch (Exception $e) {
+ logText("main/forums::getTopic: failed to fetch topic #$id (user #$user)", LOG_WARNING);
+ return null;
+ }
+ $this->topics[$idx] = $topic;
+ }
+
+ return $this->topics[$idx];
}
- // Get the amount of unread topics in a forum
- function getRead($fid, $uid) {
- $q = $this->db->query("SELECT COUNT(*) FROM f_read r,f_topic t WHERE t.id=r.topic AND t.forum=$fid AND r.reader=$uid AND t.deleted IS NULL");
- list($nr) = dbFetchArray($q);
- return $nr;
+ public function getPoll($id, $user) {
+ $idx = "$id;$user";
+
+ if (! isset($this->polls[$idx])) {
+ loader::needClasses('main/forums', 'fl_poll');
+ try {
+ $poll = new fl_poll($this->game, $user, $id);
+ } catch (Exception $e) {
+ return null;
+ }
+ $this->polls[$idx] = $poll;
+ }
+
+ return $this->polls[$idx];
}
- function switchSticky($forum, $topic) {
- $this->db->query("UPDATE f_topic SET sticky=NOT sticky WHERE id=$topic AND forum=$forum AND deleted IS NULL");
+ public function getPost($data, $user) {
+ if (is_array($data)) {
+ $id = $data['id'];
+ } else {
+ $id = $data;
+ }
+ $idx = "$id;$user";
+
+ if (! isset($this->posts[$idx])) {
+ loader::needClasses('main/forums', 'fl_post');
+ try {
+ $post = new fl_post($this->game, $user, $data);
+ } catch (Exception $e) {
+ logText("main/forums::getPost: failed to fetch post #$id (user #$user)", LOG_WARN);
+ return null;
+ }
+ $this->posts[$idx] = $post;
+ }
+
+ return $this->posts[$idx];
}
- function markForumRead($fid, $uid) {
- $q = $this->db->query("SELECT id FROM f_topic WHERE forum=$fid AND deleted IS NULL");
- while ($r = dbFetchArray($q)) {
- $this->markRead($r[0], $uid);
+ public function setOptions($pid, $forum, $perPage, $viewDeleted) {
+ if ($forum == -1) {
+ prefs::remove('main/F#PP#%');
+ prefs::remove('main/F#VD#%');
+ prefs::set('main/F#PP', $perPage);
+ prefs::set('main/F#VD', $viewDeleted ? 1 : 0);
+ } else {
+ prefs::set("main/F#PP#$forum", $perPage);
+ prefs::set("main/F#VD#$forum", $viewDeleted ? 1 : 0);
}
}
}
diff -Naur beta5//scripts/game/main/gforums/library.inc forums//scripts/game/main/gforums/library.inc
--- beta5//scripts/game/main/gforums/library.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/gforums/library.inc 2011-02-05 10:10:03.384335002 +0100
@@ -0,0 +1,165 @@
+lib = $lib;
+ $this->game = $this->lib->game;
+ $this->version = $this->game->version;
+ $this->db = $this->game->db;
+
+ $this->fLib = $this->game->getLib('main/forums');
+ loader::needClasses('main/forums', array('fl_category', 'fl_forum'));
+
+ $this->getCatQuery = $this->db->prepare(
+ "SELECT t_string,t_is_game FROM main.gf_category WHERE category = $1", array("id") );
+ $this->getCatForumsQuery = $this->db->prepare(
+ "SELECT id FROM forums.t_forum WHERE category = $1 ORDER BY f_order", array("category") );
+ $this->getForumPrivQuery = $this->db->prepare(
+ "SELECT * FROM main.get_gforums_privs( $1, $2 )", array("user", "forum") );
+ $this->getUserNameQ = $this->db->prepare( "SELECT name FROM account WHERE id = $1", array("user") );
+ }
+
+ function getStructure( $user ) {
+ $cats = array();
+
+ $q = $this->db->query("SELECT * FROM main.get_gf_categories($1, $2)",
+ $this->version->id, $this->game->name);
+ while ($r = dbFetchArray($q)) {
+ $cat = $this->fLib->call('getCategory', $r[0], $user);
+ if (! is_null($cat)) {
+ array_push($cats, $cat);
+ }
+ }
+
+ return $cats;
+ }
+
+ function getCategory( $catId , $user ) {
+ $q = $this->getCatQuery->execute($catId);
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($str, $ig) = dbFetchArray($q);
+
+ if (is_null($str)) {
+ $title = 'Legacy Worlds forums';
+ $description = 'These forums are common to all versions of Legacy Worlds after Beta 5.';
+ } else if ($ig == 'f') {
+ $txt = config::$config->versions[$str]->text;
+ $title = "Legacy Worlds {$txt}";
+ $description = "These forums are common to all games using the Legacy Worlds "
+ . "{$txt} base code.";
+ } else {
+ $txt = config::$config->games[$str]->text;
+ $title = $txt;
+ $description = "These are the forums for the {$txt} game.";
+ }
+
+ $cat = new fl_category( $this->game, $user, $catId, $title, $description );
+
+ $q = $this->getCatForumsQuery->execute($catId);
+ while ($r = dbFetchArray($q)) {
+ $forum = $this->fLib->call('getForum', $r[0], $user);
+ if ($forum->canView() && ($forum->isAdmin() || ! $forum->isDeleted())) {
+ $cat->addForum( $forum );
+ }
+ }
+
+ return $cat;
+ }
+
+
+ function getForum( $forumId, $user ) {
+ $q = $this->getForumPrivQuery->execute($user, $forumId);
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ $privs = dbFetchHash($q);
+
+ try {
+ $forum = new fl_forum( $this->game, $forumId, $user );
+ } catch (Exception $e) {
+ return null;
+ }
+
+ $forum->setAdmin( $privs['is_admin'] == 't' );
+ $forum->setMod( $privs['is_mod'] == 't' );
+ $forum->setCreateTopic( $privs['can_create'] == 't' );
+ $forum->setCreatePoll( $privs['can_poll'] == 't' );
+ $forum->setPost( $privs['can_post'] == 't' );
+ $forum->setView( $privs['can_view'] == 't' );
+
+ return $forum;
+ }
+
+
+ public function getAdmins($forum) {
+ $q = $this->db->query("SELECT category FROM forums.t_forum WHERE id = $1", $forum);
+ if (! ($q && dbCount($q) == 1)) {
+ return array();
+ }
+ list($cat) = dbFetchArray($q);
+
+ $admins = array();
+
+ $q = $this->db->query("SELECT account FROM gf_admin WHERE category = $1 OR category IS NULL", $cat);
+ if (!$q) {
+ return $admins;
+ }
+ while ($r = dbFetchArray($q)) {
+ array_push($admins, $r[0]);
+ }
+ return $admins;
+ }
+
+
+ public function getModerators($forum) {
+ $q = $this->db->query("SELECT category FROM forums.t_forum WHERE id = $1", $forum);
+ if (! ($q && dbCount($q) == 1)) {
+ return array();
+ }
+ list($cat) = dbFetchArray($q);
+
+ $mods = array();
+
+ $q = $this->db->query("SELECT account FROM gf_cat_moderator "
+ . "WHERE category = $1 OR category IS NULL", $cat);
+ if (!$q) {
+ return $mods;
+ }
+ while ($r = dbFetchArray($q)) {
+ array_push($mods, $r[0]);
+ }
+
+ $q = $this->db->query("SELECT account FROM gf_forum_moderator WHERE forum = $1", $forum);
+ if (!$q) {
+ while ($r = dbFetchArray($q)) {
+ array_push($mods, $r[0]);
+ }
+ }
+
+ return $mods;
+ }
+
+
+ public function getUsers($forum) {
+ return array();
+ }
+
+
+ public function aclIdToName($id) {
+ $q = $this->getUserNameQ->execute($id);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($rv) = dbFetchArray($q);
+ return $rv;
+ }
+}
+
+?>
diff -Naur beta5//scripts/game/main/uforums/library.inc forums//scripts/game/main/uforums/library.inc
--- beta5//scripts/game/main/uforums/library.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/game/main/uforums/library.inc 2011-02-05 10:10:03.374335002 +0100
@@ -0,0 +1,193 @@
+lib = $lib;
+ $this->game = $this->lib->game;
+ $this->db = $this->game->getDBAccess();
+
+ $this->account = $this->game->getLib('main/account');
+ $this->fLib = $this->game->getLib('main/forums');
+ loader::needClasses('main/forums', array('fl_category', 'fl_forum'));
+
+ $this->getOwnCatQ = $this->db->prepare(
+ "SELECT main.uf_get_category($1)", array("user") );
+ $this->getOtherCatsQ = $this->db->prepare(
+ "SELECT DISTINCT category FROM forums.t_forum WHERE id IN ("
+ . "SELECT forum FROM main.uf_subscription WHERE account = $1)",
+ array("user") );
+ $this->getCatOwnerQ = $this->db->prepare(
+ "SELECT account FROM main.user_category WHERE category = $1", array("category") );
+ $this->getOwnForumsQ = $this->db->prepare(
+ "SELECT id FROM forums.t_forum WHERE category = $1 ORDER BY f_order", array("category") );
+ $this->getOtherForumsQ = $this->db->prepare(
+ "SELECT id FROM forums.t_forum"
+ . " WHERE category = $1 "
+ . " AND id IN (SELECT forum FROM main.uf_subscription WHERE account = $2)"
+ . " ORDER BY f_order",
+ array("category", "user") );
+ $this->getForumPrivQ = $this->db->prepare(
+ "SELECT main.uf_get_user_access( $2, $1 )", array("forum", "user") );
+ $this->getUserNameQ = $this->db->prepare( "SELECT name FROM account WHERE id = $1", array("user") );
+ }
+
+ function getStructure( $user ) {
+ $cats = array();
+
+ $q = $this->getOwnCatQ->execute($user);
+ if ( $q && dbCount($q) == 1) {
+ list($id) = dbFetchArray($q);
+ $cat = $this->fLib->call('getCategory', $id, $user);
+ if (! is_null($cat)) {
+ array_push($cats, $cat);
+ }
+ }
+
+ $q = $this->getOtherCatsQ->execute($user);
+ while ($r = dbFetchArray($q)) {
+ $cat = $this->fLib->call('getCategory', $r[0], $user);
+ if (! is_null($cat)) {
+ array_push($cats, $cat);
+ }
+ }
+
+ return $cats;
+ }
+
+ function getCategory( $id, $user ) {
+ $q = $this->getCatOwnerQ->execute($id);
+ if (! ($q && dbCount($q) == 1) ) {
+ return null;
+ }
+ list($account) = dbFetchArray($q);
+
+ if ($account == $user) {
+ $title = "My forums";
+ $description = "These are your own forums; do with them as you please.";
+ } else {
+ $uname = $this->account->call('getUserName', $account);
+ $title = "$uname's forums";
+ $description = "These are the personnal forums of player $uname.";
+ }
+
+ $cat = new fl_category( $this->game, $user, $id, $title, $description );
+
+ if ($account == $user) {
+ $q = $this->getOwnForumsQ->execute($id);
+ if (! $q ) {
+ return null;
+ }
+ } else {
+ $q = $this->getOtherForumsQ->execute($id, $user);
+ if (! ($q && dbCount($q) ) ) {
+ return null;
+ }
+ }
+ while ($r = dbFetchArray($q)) {
+ $forum = $this->fLib->call('getForum', $r[0], $user);
+ if ($forum->canView() && ($forum->isAdmin() || ! $forum->isDeleted())) {
+ $cat->addForum( $forum );
+ }
+ }
+
+ return $cat;
+ }
+
+ function getForum( $forumId, $user) {
+ $q = $this->getForumPrivQ->execute($forumId, $user);
+ if (! ($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($accessMode) = dbFetchArray($q);
+ if (is_null($accessMode)) {
+ return null;
+ }
+
+ try {
+ $forum = new fl_forum( $this->game, $forumId, $user );
+ } catch (Exception $e) {
+ return null;
+ }
+
+ $forum->setAdmin( $accessMode == 'A' );
+ $forum->setMod( in_array($accessMode, array('M', 'A')) );
+ $forum->setCreatePoll( in_array($accessMode, array('L', 'M', 'A')) );
+ $forum->setCreateTopic( in_array($accessMode, array('T', 'L', 'M', 'A')) );
+ $forum->setPost( $accessMode != 'R' );
+ $forum->setView( true );
+
+ return $forum;
+ }
+
+
+ public function getAdmins($forum) {
+ $q = $this->db->query("SELECT uc.account FROM user_category uc, forums.t_forum f "
+ . "WHERE f.id = $1 AND uc.category = f.category", $forum);
+ if (!($q && dbCount($q) == 1)) {
+ return array();
+ }
+ list($admin) = dbFetchArray($q);
+
+ return array($admin);
+ }
+
+
+ public function getModerators($forum) {
+ $q = $this->db->query("SELECT account FROM uf_subscription WHERE access_mode = 'M' AND forum = $1",
+ $forum);
+ if (!$q) {
+ return array();
+ }
+ $mods = array();
+ while ($r = dbFetchArray($q)) {
+ array_push($mods, $r[0]);
+ }
+
+ return $mods;
+ }
+
+
+ public function getUsers($forum) {
+ $q = $this->db->query("SELECT uf_get_access_mode($1)", $forum);
+ if (!($q && dbCount($q))) {
+ return array();
+ }
+ list($mode) = dbFetchArray($q);
+ if ($mode == 'P') {
+ return array();
+ }
+
+ $q = $this->db->query("SELECT account FROM uf_subscription WHERE access_mode <> 'M' AND forum = $1",
+ $forum);
+ if (!$q) {
+ return array();
+ }
+ $users = array();
+ while ($r = dbFetchArray($q)) {
+ array_push($users, $r[0]);
+ }
+
+ return $users;
+ }
+
+
+ public function aclIdToName($id) {
+ $q = $this->getUserNameQ->execute($id);
+ if (!($q && dbCount($q) == 1)) {
+ return null;
+ }
+ list($rv) = dbFetchArray($q);
+ return $rv;
+ }
+}
+
+
+?>
diff -Naur beta5//scripts/lib/classloader.inc forums//scripts/lib/classloader.inc
--- beta5//scripts/lib/classloader.inc 2011-02-05 10:09:57.434335002 +0100
+++ forums//scripts/lib/classloader.inc 2011-03-12 14:56:22.471300053 +0100
@@ -20,6 +20,17 @@
array_push(loader::$loadedClasses, $className);
}
+
+ static function needClasses($basePath, $classes) {
+ $path = config::$main['scriptdir'] . "/game/$basePath/";
+ if (!is_array($classes)) {
+ $classes = array($classes);
+ }
+
+ foreach ($classes as $cn) {
+ self::load($path . $cn . ".inc", $cn);
+ }
+ }
}
?>
diff -Naur beta5//scripts/lib/config.inc forums//scripts/lib/config.inc
--- beta5//scripts/lib/config.inc 2011-02-05 10:09:57.434335002 +0100
+++ forums//scripts/lib/config.inc 2011-03-12 14:56:24.031300053 +0100
@@ -123,6 +123,10 @@
static function getParam($name) {
return config::$config->games['main']->params[$name];
}
+
+ static function getMainInterface() {
+ return config::$config->games['main'];
+ }
}
config::load();
diff -Naur beta5//scripts/lib/db_accessor.inc forums//scripts/lib/db_accessor.inc
--- beta5//scripts/lib/db_accessor.inc 2011-02-05 10:09:57.434335002 +0100
+++ forums//scripts/lib/db_accessor.inc 2011-03-12 15:30:19.021300053 +0100
@@ -32,9 +32,15 @@
$this->db->disableExceptions();
}
- public function query($q) {
+ public function query() {
$this->setNamespace();
- return $this->db->query($q);
+ $args = func_get_args();
+ return call_user_func_array(array($this->db, "query"), $args);
+ }
+
+ public function prepare($q, $params) {
+ $this->setNamespace();
+ return db_query::getQuery($this, $q, $params);
}
public function begin() {
@@ -45,6 +51,14 @@
return $this->db->end($rb);
}
+ public function getNamespace() {
+ return $this->namespace;
+ }
+
+ public function getDatabase() {
+ return $this->db;
+ }
+
public function needsReset() {
return $this->db->needsReset();
}
diff -Naur beta5//scripts/lib/db_connection.inc forums//scripts/lib/db_connection.inc
--- beta5//scripts/lib/db_connection.inc 2011-02-05 10:09:57.434335002 +0100
+++ forums//scripts/lib/db_connection.inc 2011-03-12 15:39:08.891300050 +0100
@@ -229,17 +229,22 @@
return true;
}
- public function query($query) {
- if (!$this->inTrans) {
- $this->fail("query executed outside of transaction", $query);
- return null;
+ public function query() {
+ if (func_num_args() == 1) {
+ $query = func_get_arg(0);
+ if (!$this->checkQuery($query)) {
+ return null;
+ }
+ $r = @pg_query($this->conn, $query);
+ } else {
+ $args = func_get_args();
+ $query = array_shift($args);
+ if (!$this->checkQuery($query)) {
+ return null;
+ }
+ $r = call_user_func("pg_query_params", $query, $args);
}
- $this->queries ++;
- if ($this->trace) {
- l::trace("EXECUTE: $query");
- }
- $r = @pg_query($this->conn, $query);
if (!$r) {
$cStat = pg_connection_status($this->conn);
$error = pg_last_error($this->conn);
@@ -264,48 +269,23 @@
}
} elseif (preg_match('/^\s*insert\s+into ("?\w+"?)/i', $query, $match)) {
pg_free_result($r);
-
- $tn = $match[1];
- if ($tn{0} == '"') {
- $tn = str_replace('"', '', $tn);
- } else {
- $tn = strtolower($tn);
- }
-
- $r2 = @pg_query("SELECT last_inserted('$tn')");
- if ($r2) {
- $rv = pg_fetch_row($r2);
- if (is_null($rv[0])) {
- $r = true;
- } else {
- $r = $rv[0];
- }
- pg_free_result($r2);
- } elseif (preg_match('/deadlock/i', $error)) {
- l::error("SQL: deadlock detected");
- if ($this->useExceptions) {
- throw new db_deadlock_exception($error);
- }
- $this->error = true;
- return;
- } else {
- $cStat = pg_connection_status($this->conn);
- $error = pg_last_error($this->conn);
- if ($cStat == PGSQL_CONNECTION_BAD) {
- l::notice("SQL: connection is gone while fetching last ID");
- $this->__needsReset = true;
- if ($this->useExceptions) {
- throw new db_srv_exception($error);
- }
- } else {
- $this->fail("failed to fetch last ID: $error", "SELECT last_inserted('$tn')");
- }
- $r = null;
- }
+ $r = $this->getLastInserted($match[1]);
}
return $r;
}
+ private function checkQuery($query) {
+ if (!$this->inTrans) {
+ $this->fail("SQL: query executed outside of transaction", $query);
+ return false;
+ }
+ if ($this->trace) {
+ l::trace("EXECUTE: $query");
+ }
+ $this->queries ++;
+ return true;
+ }
+
public function getGameAccess($prefix) {
if (is_null($this->accessors[$prefix])) {
$this->accessors[$prefix] = new db_accessor($this, $prefix);
@@ -313,6 +293,50 @@
return $this->accessors[$prefix];
}
+ public function getConnection() {
+ return $this->conn;
+ }
+
+ private function getLastInserted($tn) {
+ if ($tn{0} == '"') {
+ $tn = str_replace('"', '', $tn);
+ } else {
+ $tn = strtolower($tn);
+ }
+
+ $r2 = @pg_query("SELECT last_inserted('$tn')");
+ if ($r2) {
+ $rv = pg_fetch_row($r2);
+ if (is_null($rv[0])) {
+ $r = true;
+ } else {
+ $r = $rv[0];
+ }
+ pg_free_result($r2);
+ } elseif (preg_match('/deadlock/i', $error)) {
+ l::error("SQL: deadlock detected");
+ if ($this->useExceptions) {
+ throw new db_deadlock_exception($error);
+ }
+ $this->error = true;
+ $r = null;
+ } else {
+ $cStat = pg_connection_status($this->conn);
+ $error = pg_last_error($this->conn);
+ if ($cStat == PGSQL_CONNECTION_BAD) {
+ l::notice("SQL: connection is gone while fetching last ID");
+ $this->__needsReset = true;
+ if ($this->useExceptions) {
+ throw new db_srv_exception($error);
+ }
+ } else {
+ $this->fail("failed to fetch last ID: $error", "SELECT last_inserted('$tn')");
+ }
+ $r = null;
+ }
+ return $r;
+ }
+
public function needsReset() {
return $this->__needsReset;
}
diff -Naur beta5//scripts/lib/db_query.inc forums//scripts/lib/db_query.inc
--- beta5//scripts/lib/db_query.inc 1970-01-01 01:00:00.000000000 +0100
+++ forums//scripts/lib/db_query.inc 2011-02-05 10:10:03.074335002 +0100
@@ -0,0 +1,132 @@
+accessor = $accessor;
+ $this->query = $query;
+ $this->parameters = $pNames;
+ $this->name = $name;
+
+ $this->database = $this->accessor->getDatabase();
+ $this->connection = $this->database->getConnection();
+
+ $this->accessor->useNamespace();
+ $r = @pg_prepare($this->connection, $this->name, $query);
+
+ if (! $r) {
+ $this->accessor->getDatabase()->fail(
+ "SQL: Could not prepare query: " . pg_last_error($this->connection),
+ $this->query );
+ throw new Exception('failed');
+ }
+
+ if (preg_match('/^\s*insert\s+into ("?\w+"?)/i', $this->query, $match)) {
+ $this->table = $match[1];
+ }
+ }
+
+
+ public function execute() {
+ if ($this->counter == 0) {
+ $this->database->fail(
+ "SQL: tried to execute de-allocated query",
+ $this->query );
+ return null;
+ }
+ if (!$this->database->checkQuery($this->query)) {
+ return null;
+ }
+
+ $args = func_get_args();
+ if (count($args) == 1 && is_array($args[0])) {
+ $params = $args[0];
+ $p = array();
+ for ($i = 0; $i < count($this->parameters); $i ++) {
+ if (!array_key_exists($this->parameters[$i], $params)) {
+ $this->database->fail(
+ "SQL: missing parameter '{$this->parameters[$i]}' for prepared query",
+ $this->query );
+ return null;
+ }
+ $p[$i] = $params[$this->parameters[$i]];
+ }
+ } elseif (count($args) == count($this->parameters)) {
+ $p = $args;
+ } else {
+ $this->database->fail( "SQL: invalid parameters for prepared query", $this->query );
+ return null;
+ }
+
+ $this->accessor->useNamespace();
+ $r = @pg_execute($this->connection, $this->name, $p);
+
+ if (! $r) {
+ $this->database->fail(
+ "SQL: could not execute prepared query: " . pg_last_error($this->connection),
+ $this->query );
+ return null;
+ }
+
+ if (!is_null($this->table)) {
+ pg_free_result($r);
+ $r = $this->database->getLastInserted($this->table);
+ }
+
+ return $r;
+ }
+
+ public function destroy($force = false) {
+ if ($this->counter == 0) {
+ return;
+ }
+
+ if ($force) {
+ $this->counter = 0;
+ } else {
+ $this->counter --;
+ }
+
+ if ($this->counter == 0) {
+ $this->accessor->useNamespace();
+ $r = $this->database->query("DEALLOCATE {$this->name}");
+ self::$queries[$this->name] = null;
+ }
+ }
+
+
+ public static function getQuery($accessor, $query, $pNames) {
+ $data = array(
+ "n" => $accessor->getNamespace(),
+ "q" => $query,
+ "p" => $pNames
+ );
+ $name = "q_" . strtolower(md5(serialize($data)));
+
+ if (is_null(self::$queries[$name])) {
+ try {
+ self::$queries[$name] = new db_query($name, $accessor, $query, $pNames);
+ } catch (Exception $e) {
+ return null;
+ }
+ } else {
+ self::$queries[$name]->counter ++;
+ }
+ return self::$queries[$name];
+ }
+
+}
+
+?>
diff -Naur beta5//scripts/lib/library.inc forums//scripts/lib/library.inc
--- beta5//scripts/lib/library.inc 2011-02-05 10:09:57.434335002 +0100
+++ forums//scripts/lib/library.inc 2011-03-12 14:56:22.481300053 +0100
@@ -66,10 +66,28 @@
$fcn = $this->loadClass($this->functions[$function][1]);
$this->functions[$function][2] = new $fcn($this);
}
- $rv = call_user_func_array(array($this->functions[$function][2], 'run'), $args);
+ try {
+ $rv = call_user_func_array(array($this->functions[$function][2], 'run'), $args);
+ } catch (Exception $e) {
+ fatalError(32, array(
+ "Function call '{$this->name}::$function' on game '{$this->game->name}' "
+ . "failed with exception:",
+ $e->getMessage()
+ ));
+ }
} else {
// Call the function instance's method
- $rv = call_user_func_array(array($this->mainClass, $this->functions[$function][1]), $args);
+ try {
+ $rv = call_user_func_array(
+ array($this->mainClass, $this->functions[$function][1]), $args
+ );
+ } catch (Exception $e) {
+ fatalError(32, array(
+ "Function call '{$this->name}::$function' on game '{$this->game->name}' "
+ . "failed with exception:",
+ $e->getMessage()
+ ));
+ }
}
return $rv;
diff -Naur beta5//scripts/lib/prefs.inc forums//scripts/lib/prefs.inc
--- beta5//scripts/lib/prefs.inc 2011-02-05 10:09:57.434335002 +0100
+++ forums//scripts/lib/prefs.inc 2011-02-05 10:10:03.074335002 +0100
@@ -107,6 +107,19 @@
return $v;
}
+ static function remove($path) {
+ list($version, $name) = explode('/', $path);
+ $qs = "DELETE FROM user_preferences WHERE account={$_SESSION['userid']} AND version = '$version' AND id";
+ if (strstr($name, '%') === FALSE) {
+ $q = dbQuery("$qs = '$name'");
+ } else {
+ $q = dbQuery("$qs LIKE '$name'");
+ }
+ prefs::$prefs = null;
+ prefs::load();
+
+ }
+
}
?>
diff -Naur beta5//scripts/site/beta5/handlers/alliance.inc forums//scripts/site/beta5/handlers/alliance.inc
--- beta5//scripts/site/beta5/handlers/alliance.inc 2011-02-05 10:09:57.204335002 +0100
+++ forums//scripts/site/beta5/handlers/alliance.inc 2011-03-12 15:16:23.151300053 +0100
@@ -18,8 +18,8 @@
// Pending requests
"getPending", "acceptRequests", "rejectRequests",
// Forums
- "getForums", "newForum", "changeForum", "delForum",
- "moveForum", "getForumAcl",
+ "getForums", "newForum", "changeForum",
+ "delForum", "restoreForum", "moveForum",
// Ranks
"getRanks", "newRank", "changeRank", "delRank"
),
@@ -802,190 +802,316 @@
// ALLIANCE FORUMS MANAGEMENT
//-------------------------------------------
- function doGetForums($aid) {
- $afl = gameAction('getAllianceForums', $aid);
- $s = "";
- foreach ($afl as $id => $afd)
- {
- if ($s != "")
- $s .= "\n";
- $s .= "$id#" . $afd['order'] . "#" . ($afd['user_post'] ? 1 : 0) . "#" . $afd['title'];
- if ($afd['description'] != '')
- {
- $dll = split("\n", $afd['description']);
- foreach ($dll as $dl)
- $s .= "\n+#$dl";
+ private function forumsGetLibraries() {
+ // Get the libraries
+ $this->player = input::$game->getLib('beta5/player');
+ $this->alliance = input::$game->getLib('beta5/alliance');
+ $this->forums = input::$game->getLib('main/forums');
+ $this->aForums = input::$game->getLib('beta5/aforums');
+ }
+
+ private function doGetForums($aid, $uid) {
+ $out = array();
+ $players = array();
+
+ // Get the category and output the amount of forums
+ $cat = array_shift($this->aForums->call('getStructure', $uid));
+ array_push($out, count($cat->getForums()));
+ $admin = null;
+
+ foreach ($cat->getForums() as $forum) {
+ // Get general information regarding the forum
+ $fid = $forum->getId();
+ $userPrivs = $this->aForums->call('getUserPrivileges', $fid);
+ $topics = $forum->getTopics();
+ $name = $forum->getTitle();
+
+ // Get information about the forum's deletion
+ $deleted = $forum->isDeleted() ? '1' : '0';
+ $deletedAt = $forum->deletedAt();
+ $deletedBy = $forum->deletedBy();
+ if (! (is_null($deletedBy) || in_array($deletedBy, $players))) {
+ array_push($players, $deletedBy);
+ }
+
+ // Output general information
+ array_push($out, "$fid#$deleted#$deletedBy#$deletedAt#$userPrivs#$topics#$name");
+
+ // Get the rank-specific access privileges for that forum
+ array_push($out, join('#', $forum->getUsers()));
+ array_push($out, join('#', $forum->getModerators()));
+ $admins = $forum->getAdministrators();
+
+ // Get the description
+ $description = $forum->getDescription();
+ if (is_null($description) || $description == '') {
+ array_push($out, "0");
+ } else {
+ $dList = explode("\n", $description);
+ array_push($out, count($dList));
+ foreach ($dList as $dLine) {
+ array_push($out, $dLine);
+ }
}
}
- return $s;
+
+ // Get the rank names
+ $ranks = $this->alliance->call('getRanks', $aid);
+ array_push($out, count($ranks));
+ foreach ($ranks as $rId => $rName) {
+ array_push($out, "$rId#" . utf8entities($rName));
+ }
+
+ // List the ranks having administrator privileges
+ if (is_null($admins)) {
+ $admins = array();
+ foreach ($ranks as $rId => $rName) {
+ $rkp = $this->alliance->call('getRankPrivileges', $rId);
+ if ($rkp['forum_admin']) {
+ array_push($admins, $rId);
+ }
+ }
+ }
+ array_push($out, join('#', $admins));
+
+ // Get the player names (for forums that have been deleted)
+ array_push($out, count($players));
+ foreach ($players as $pid) {
+ array_push($out, "$pid#" . utf8entities($this->player->call('getName', $pid, true)));
+ }
+
+ return join("\n", $out);
}
- function getForums() {
+ public function getForums() {
$pid = $_SESSION[game::sessName()]['player'];
- $p = gameAction('getPlayerInfo', $pid);
+ $this->forumsGetLibraries();
+
+ // Check if the player's in an alliance
+ $p = $this->player->call('get', $pid);
if (is_null($p['aid'])) {
return "ERR#0";
}
+
+ // Check if the player is a forums administrator
$aid = $p['aid'];
- $pr = gameAction('getAlliancePrivileges', $pid);
+ $pr = $this->alliance->call('getPrivileges', $pid);
if (!$pr['forum_admin']) {
return "ERR#4";
}
- $_SESSION[game::sessName()]['alliance_page'] = 'FAdmin';
- return $this->doGetForums($aid);
+ $_SESSION[game::sessName()]['alliance_page'] = 'FAdmin';
+ return $this->doGetForums($aid, $p['uid']);
}
- function newForum($name, $userPost, $after, $description, $acl) {
- if (gameAction('isOnVacation', $_SESSION[game::sessName()]['player'])) {
- return "ERR#200";
+ private function setForumPrivileges( $forum, $alliance, $acl ) {
+ $rl = $this->alliance->call('getRanks', $alliance);
+ $acla = explode('#', $acl);
+ $forum->clearACL();
+
+ foreach ($acla as $as) {
+ list($rank, $level) = explode('!', $as);
+ $level --;
+ if (is_null($rl[$rank]) || ($level != 0 && $level != 1)) {
+ continue;
+ }
+
+ if ($level) {
+ $forum->addModerator($rank);
+ } else {
+ $forum->addUser($rank);
+ }
}
+ }
+
+ public function newForum($name, $accessMode, $after, $description, $acl) {
+ $this->forumsGetLibraries();
$pid = $_SESSION[game::sessName()]['player'];
- $p = gameAction('getPlayerInfo', $pid);
- if (is_null($p['aid']))
- return "ERR#0";
- $aid = $p['aid'];
- $pr = gameAction('getAlliancePrivileges', $pid);
- if (!$pr['forum_admin'])
- return "ERR#4";
+ $p = $this->player->call('get', $pid);
- $afl = gameAction('getAllianceForums', $aid);
- if (count($afl) >= 30) {
- return "ERR#5";
+ if (is_null($p['aid'])) {
+ return "ERR#0\n0";
}
- $name = preg_replace('/\s+/', ' ', trim($name));
- if ($name == "" || strlen($name) < 4)
- return "ERR#1";
- foreach ($afl as $fid => $fd)
- if ($fd['title'] == $name)
- return "ERR#2";
-
- if ($after != "-1" && is_null($afl[$after]))
- return "ERR#6";
-
- $description = trim($description);
- gameAction('newAllianceForum', $aid, $name, ($userPost == 1), $after, $description);
-
- $afl = gameAction('getAllianceForums', $aid);
- $mId = false;
- foreach ($afl as $fid => $fd)
- if ($fd['title'] == $name)
- {
- $mId = $fid;
- break;
+ if ($this->player->call('isOnVacation', $pid)) {
+ $err = 200;
+ } else {
+ $name = preg_replace('/\s+/', ' ', trim($name));
+ $description = trim($description);
+ $cat = array_shift($this->aForums->call('getStructure', $p['uid']));
+ $after = (int) $after;
+
+ if ($name == "" || strlen($name) < 4) {
+ $err = 1;
+ } elseif ($after != -1 && is_null($cat->findForum($after))) {
+ $err = 6;
+ } else {
+ if ($after == -1) {
+ $order = 0;
+ } else {
+ $order = $cat->findForum($after)->getOrder() + 1;
+ }
+
+ $rv = $this->aForums->call('create',
+ $pid, $p['uid'], $p['aid'], $order,
+ $name, $description, $accessMode
+ );
+ if (is_object($rv)) {
+ $this->setForumPrivileges( $rv, $p['aid'], $acl );
+ $err = null;
+ } else {
+ logText("Alliance forum creation returned $rv");
+ switch ($rv) :
+ case 1: $err = 0; break;
+ case 2: $err = 4; break;
+ case 3: $err = 5; break;
+ case 4: $err = 2; break;
+ default: $err = 7; break;
+ endswitch;
+ }
}
- if (!$mId) {
- return "ERR#7";
}
- $rl = gameAction('getAllianceRanks', $aid);
- $fread = $fmod = array();
- $acla = explode('#', $acl);
- foreach ($acla as $as)
- {
- list($rank,$level) = explode('!', $as);
- $level --;
- if (is_null($rl[$rank]) || ($level != 0 && $level != 1))
- continue;
- if ($level)
- array_push($fmod, $rank);
- else
- array_push($fread, $rank);
+ $out = $this->doGetForums($p['aid'], $p['uid']);
+ if (!is_null($err)) {
+ $out = "ERR#$err\n$out";
}
- gameAction('setForumAccess', $mId, $fread, $fmod);
-
- return $this->doGetForums($aid);
+ return $out;
}
- function changeForum($id, $name, $userPost, $description, $acl) {
- if (gameAction('isOnVacation', $_SESSION[game::sessName()]['player'])) {
- return "ERR#200";
- }
-
+ public function changeForum($id, $name, $accessMode, $description, $acl) {
+ $this->forumsGetLibraries();
$pid = $_SESSION[game::sessName()]['player'];
- $p = gameAction('getPlayerInfo', $pid);
- if (is_null($p['aid']))
- return "ERR#0";
- $aid = $p['aid'];
- $pr = gameAction('getAlliancePrivileges', $pid);
- if (!$pr['forum_admin'])
- return "ERR#1";
-
- $afl = gameAction('getAllianceForums', $aid);
- if (is_null($afl[$id]))
- return "ERR#3";
+ $p = $this->player->call('get', $pid);
- $name = preg_replace('/\s+/', ' ', trim($name));
- if ($name == "" || strlen($name) < 4)
- return "ERR#1";
- foreach ($afl as $fid => $fd)
- if ($fid != $id && $fd['name'] == $name)
- return "ERR#2";
-
- $description = trim($description);
- gameAction('modifyAllianceForum', $id, $name, ($userPost == 1), $description);
+ if (is_null($p['aid'])) {
+ return "ERR#0\n0";
+ }
- $rl = gameAction('getAllianceRanks', $aid);
- $fread = $fmod = array();
- $acla = explode('#', $acl);
- foreach ($acla as $as)
- {
- list($rank,$level) = explode('!', $as);
- $level --;
- if (is_null($rl[$rank]) || ($level != 0 && $level != 1))
- continue;
- if ($level)
- array_push($fmod, $rank);
- else
- array_push($fread, $rank);
+ if ($this->player->call('isOnVacation', $pid)) {
+ $err = 200;
+ } else {
+ $id = (int) $id;
+ $name = preg_replace('/\s+/', ' ', trim($name));
+ $description = trim($description);
+
+ $rv = $this->aForums->call('modifyForum', $id, $pid, $name, $description, $accessMode);
+ if ($rv > 0) {
+ switch ($rv) :
+ case -1: $err = 7; break;
+ case -2: $err = 0; break;
+ case -3: $err = 4; break;
+ case -4: $err = 8; break;
+ case -5: $err = 7; break;
+ endswitch;
+ } else {
+ $err = null;
+ $this->setForumPrivileges( $this->forums->call('getForum', $id, $p['uid']),
+ $p['aid'], $acl );
+ }
}
- gameAction('setForumAccess', $id, $fread, $fmod);
- return $this->doGetForums($aid);
+ $out = $this->doGetForums($p['aid'], $p['uid']);
+ if (!is_null($err)) {
+ $out = "ERR#$err\n$out";
+ }
+ return $out;
}
function delForum($id) {
- if (gameAction('isOnVacation', $_SESSION[game::sessName()]['player'])) {
- return "ERR#200";
+ $this->forumsGetLibraries();
+ $pid = $_SESSION[game::sessName()]['player'];
+ $p = $this->player->call('get', $pid);
+
+ if (is_null($p['aid'])) {
+ $err = 0;
+ $out = "0";
+ } else {
+ if ($this->player->call('isOnVacation', $pid)) {
+ $err = 200;
+ } else {
+ $f = $this->forums->call('getForum', (int) $id, $p['uid']);
+ if (is_null($f) || $f->isDeleted()) {
+ $err = 8;
+ } elseif (! $f->isAdmin()) {
+ $err = 4;
+ } else {
+ $f->delete();
+ $err = null;
+ }
+ }
+ $out = $this->doGetForums($p['aid'], $p['uid']);
}
+ if (!is_null($err)) {
+ $out = "ERR#$err\n$out";
+ }
+ return $out;
+ }
+
+ function restoreForum($id) {
+ $this->forumsGetLibraries();
$pid = $_SESSION[game::sessName()]['player'];
- $p = gameAction('getPlayerInfo', $pid);
- if (is_null($p['aid']))
- return "ERR#0";
- $aid = $p['aid'];
- $pr = gameAction('getAlliancePrivileges', $pid);
- if (!$pr['forum_admin'])
- return "ERR#1";
+ $p = $this->player->call('get', $pid);
- $afl = gameAction('getAllianceForums', $aid);
- if (is_null($afl[$id])) {
- return "ERR#8";
+ if (is_null($p['aid'])) {
+ $err = 0;
+ $out = "0";
+ } else {
+ if ($this->player->call('isOnVacation', $pid)) {
+ $err = 200;
+ } else {
+ $f = $this->forums->call('getForum', (int) $id, $p['uid']);
+ if (is_null($f)) {
+ $err = 9;
+ } elseif (! $f->isAdmin()) {
+ $err = 4;
+ } elseif (! $f->isDeleted()) {
+ $err = 9;
+ } else {
+ $f->restore();
+ $err = null;
+ }
+ }
+ $out = $this->doGetForums($p['aid'], $p['uid']);
}
- gameAction('deleteAllianceForum', $id);
- return $this->doGetForums($aid);
- }
- function moveForum($id, $up) {
- if (gameAction('isOnVacation', $_SESSION[game::sessName()]['player'])) {
- return "ERR#200";
+ if (!is_null($err)) {
+ $out = "ERR#$err\n$out";
}
+ return $out;
+ }
+ function moveForum($id, $up) {
+ $this->forumsGetLibraries();
$pid = $_SESSION[game::sessName()]['player'];
- $p = gameAction('getPlayerInfo', $pid);
- if (is_null($p['aid']))
- return "ERR#0";
- $aid = $p['aid'];
- $pr = gameAction('getAlliancePrivileges', $pid);
- if (!$pr['forum_admin'])
- return "ERR#1";
+ $p = $this->player->call('get', $pid);
+
+ if (is_null($p['aid'])) {
+ $err = 0;
+ $out = "0";
+ } else {
+ if ($this->player->call('isOnVacation', $pid)) {
+ $err = 200;
+ } else {
+ $f = $this->forums->call('getForum', (int) $id, $p['uid']);
+ if (is_null($f) || $f->isDeleted()) {
+ $err = 8;
+ } elseif (! $f->isAdmin()) {
+ $err = 4;
+ } else {
+ $f->move($up == '1');
+ $err = null;
+ }
+ }
+ $out = $this->doGetForums($p['aid'], $p['uid']);
+ }
- $afl = gameAction('getAllianceForums', $aid);
- if (!is_null($afl[$id]))
- gameAction('moveAllianceForum', $id, ($up == "1"));
- return $this->doGetForums($aid);
+ if (!is_null($err)) {
+ $out = "ERR#$err\n$out";
+ }
+ return $out;
}
function getForumAcl($id) {
diff -Naur beta5//scripts/site/beta5/handlers/comms.inc forums//scripts/site/beta5/handlers/comms.inc
--- beta5//scripts/site/beta5/handlers/comms.inc 2011-02-05 10:09:57.204335002 +0100
+++ forums//scripts/site/beta5/handlers/comms.inc 2011-03-12 15:21:17.911300054 +0100
@@ -8,6 +8,50 @@
'init' => "makeCommsTooltips();\ninitPage();"
);
+ /** This method dumps containers, categories and forums to the output data.
+ * The dump's format is the following:
+ *
+ * type # id # nElements # topics # unread
+ * name
+ *
+ * With:
+ * "type" being either "C" for categories and containers or "F" for forums
+ * "id" being the object's identifier
+ * "nElements" is the number of sub-elements the object contains
+ * "topics" and "unread" are the amount of topics and unread topics
+ * "name" is the object's title
+ *
+ * \parameter $result a reference to the output data
+ * \parameter $container the object to be dumped
+ */
+ private function dumpForums( &$result, $container ) {
+ $res = array();
+
+ if ( $container instanceof fl_forum ) {
+ array_push($res, 'F');
+ $contents = array();
+ } else {
+ array_push($res, 'C');
+ if ( $container instanceof fl_category ) {
+ $contents = $container->getForums();
+ } else {
+ $contents = $container->getCategories();
+ }
+ }
+
+ array_push( $res, $container->getId() );
+ array_push( $res, count($contents) );
+ array_push( $res, $container->getTopics() );
+ array_push( $res, $container->getUnread() );
+
+ array_push( $result, join('#', $res) );
+ array_push( $result, utf8entities($container->getTitle()));
+
+ foreach ($contents as $c) {
+ $this->dumpForums( &$result, $c );
+ }
+ }
+
public function getCommsData() {
// Get the data
$data = $this->game->action('getCommsOverview', $_SESSION[game::sessName()]['player']);
@@ -16,33 +60,20 @@
$result = array();
array_push($result, count($data['folders']['CUS']) . "#" . count($data['forums']['general'])
. "#" . count($data['forums']['alliance']));
-
- // Messages in default folders
- $dFld = array('IN', 'INT', 'OUT');
- foreach ($dFld as $f) {
- array_push($result, join('#', $data['folders'][$f]));
- }
-
- // Custom folders
foreach ($data['folders']['CUS'] as $id => $folder) {
$folder[2] = utf8entities($folder[2]);
array_unshift($folder, $id);
array_push($result, join('#', $folder));
}
+
// Forums
- foreach ($data['forums']['general'] as $cat) {
- array_push($result, "{$cat['id']}#{$cat['type']}#" . count($cat['forums'])
- . "#" . utf8entities($cat['title']));
-
- foreach ($cat['forums'] as $f) {
- $f[3] = utf8entities($f[3]);
- array_push($result, join('#', $f));
- }
- }
- foreach ($data['forums']['alliance'] as $f) {
- $f[3] = utf8entities($f[3]);
- array_push($result, join('#', $f));
+ $forums = gameAction('getForums', $pid);
+ if (is_null($forums)) {
+ array_push($result, "C#/#0#0#0");
+ array_push($result, "");
+ } else {
+ $this->dumpForums( &$result, $forums );
}
return join("\n", $result);
diff -Naur beta5//scripts/site/beta5/handlers/diplomacy.inc forums//scripts/site/beta5/handlers/diplomacy.inc
--- beta5//scripts/site/beta5/handlers/diplomacy.inc 2011-02-05 10:09:57.204335002 +0100
+++ forums//scripts/site/beta5/handlers/diplomacy.inc 2011-02-05 10:10:02.884335002 +0100
@@ -1,7 +1,12 @@
array('getInformation'),
@@ -9,9 +14,6 @@
);
function getAllianceRanking($tag) {
- if (! $this->rkLib) {
- $this->rkLib = input::$game->getLib('main/rankings');
- }
$rt = $this->rkLib->call('getType', "a_general");
$r = $this->rkLib->call('get', $rt, $tag);
if (!$r) {
@@ -20,27 +22,33 @@
return $r;
}
- function getInformation()
- {
+ function getInformation() {
$out = array();
$pid = $_SESSION[game::sessName()]['player'];
- $pinf = gameAction('getPlayerInfo', $pid);
- if (!is_null($pinf['arid']))
- {
- $ainf = gameAction('getAllianceInfo', $pinf['arid']);
+
+ // Get the libraries
+ $this->rkLib = input::$game->getLib('main/rankings');
+ $this->player = input::$game->getLib('beta5/player');
+ $this->alliance = input::$game->getLib('beta5/alliance');
+
+ $pinf = $this->player->call('get', $pid);
+
+ // Player has requested to join an alliance
+ if (!is_null($pinf['arid'])) {
+ $ainf = $this->alliance->call('get', $pinf['arid']);
$s = "1#" . $ainf['nplanets'] . '#' . $ainf['avgx'] . '#' . $ainf['avgy'];
list($points,$ranking) = $this->getAllianceRanking($ainf['tag']);
$s .= "#$ranking#$points";
array_push($out, $s);
array_push($out, utf8entities($pinf['alliance_req']));
array_push($out, utf8entities($pinf['aname']));
- $alinf = gameAction('getPlayerName', $ainf['leader']);
+ $alinf = $this->player->call('getName', $ainf['leader']);
array_push($out, utf8entities($alinf));
- }
- elseif (!is_null($pinf['aid']))
- {
- $ainf = gameAction('getAllianceInfo', $pinf['aid']);
- $pr = gameAction('getAlliancePrivileges', $pid);
+
+ // Player is a member of an alliance
+ } elseif (!is_null($pinf['aid'])) {
+ $ainf = $this->alliance->call('get', $pinf['aid']);
+ $pr = $this->alliance->call('getPrivileges', $pid);
$s = "2#" . $ainf['nplanets'] . '#' . $ainf['avgx'] . '#' . $ainf['avgy'];
list($points,$ranking) = $this->getAllianceRanking($ainf['tag']);
@@ -49,31 +57,36 @@
array_push($out, $s);
array_push($out, utf8entities($pinf['alliance']));
array_push($out, utf8entities($pinf['aname']));
- if (!$pr['is_leader'])
- {
- array_push($out, utf8entities(gameAction('getPlayerName', $ainf['leader'])));
- if (is_null($pinf['a_grade']))
+
+ // Get the player's rank if he isn't the leader
+ if (!$pr['is_leader']) {
+ array_push($out, utf8entities($this->player->call('getName', $ainf['leader'])));
+ if (is_null($pinf['a_grade'])) {
array_push($out, "-");
- else
- {
- $rkl = gameAction('getAllianceRanks', $pinf['aid']);
+ } else {
+ $rkl = $this->alliance->call('getRanks', $pinf['aid']);
array_push($out, $rkl[$pinf['a_grade']]);
}
}
- $fl = gameAction('getAllianceForumsComplete', $pinf['aid']);
- foreach ($fl as $fd)
- {
- $fid = $fd['id'];
- if (!(in_array($fid, $pr['f_read']) || in_array($fid, $pr['f_mod'])))
+ // Get the list of alliance forums
+ $aForums = input::$game->getLib('beta5/aforums');
+ $cat = array_shift($aForums->call('getStructure', $pinf['uid']));
+ foreach ($cat->getForums() as $forum) {
+ if ($forum->isDeleted()) {
continue;
- $tot = $fd['topics'];
- $unread = $tot - gameAction('getReadTopics', $fid, $pid);
- array_push($out, "$fid#$tot#$unread#".utf8entities($fd['title']));
+ }
+ $fid = $forum->getId();
+ $tot = $forum->getTopics();
+ $unread = $forum->getUnread();
+ $name = utf8entities($forum->getTitle());
+ array_push($out, "$fid#$tot#$unread#$name");
}
- }
- else
+
+ // Player is not a member of any alliance and has not requested to join one
+ } else {
array_push($out, "0");
+ }
$pm = gameAction('getAllMessages', $pid, 'IN');
$pmn = gameAction('getNewMessages', $pid, 'IN');
diff -Naur beta5//scripts/site/beta5/handlers/forums.inc forums//scripts/site/beta5/handlers/forums.inc
--- beta5//scripts/site/beta5/handlers/forums.inc 2011-02-05 10:09:57.204335002 +0100
+++ forums//scripts/site/beta5/handlers/forums.inc 2011-03-12 14:56:16.341300049 +0100
@@ -1,9 +1,7 @@
output = "forums";
}
+*/
+ /* Timeout in seconds for the forums' session data */
+ const SESSION_TIMEOUT = 60;
+
+ /* AJAX engine data */
+ public $needsAuth = true;
+ public $ajax = array(
+ "init" => "main = new ForumsLayout();",
+ "func" => array(
+ // Menu functions
+ "showMenu", "hideMenu", "getMenu",
+ "menuOpen", "menuClose",
+ // Category / forum view functions
+ "getView", "categoryRead", "forumOptions", "forumRead",
+ "restoreTopics", "deleteTopics", "changeTopicsLevel",
+ "setTopicsLevel", "setTopicsLock", "moveTopics",
+ // Topic view functions
+ "getTopic", "loadPostContents"
+ ));
+
+ /* Method that loads the required libraries */
+ private function loadLibraries() {
+ $this->player = input::$game->getLib('beta5/player');
+
+ $this->forums = input::$game->getLib('main/forums');
+ $this->gForums = input::$game->getLib('main/gforums');
+ $this->uForums = input::$game->getLib('main/uforums');
+ $this->aForums = input::$game->getLib('beta5/aforums');
+ }
+
+
+/***********************************************************************************************************************/
+/** SESSION CODE *******************************************************************************************************/
+/***********************************************************************************************************************/
+
+ /* This method reads the menu's status from the session */
+ private function getMenuSession() {
+ if (! array_key_exists( 'forums_menu', $_SESSION[game::sessName()] )) {
+ $_SESSION[game::sessName()]['forums_menu'] = array();
+ }
+ return $_SESSION[game::sessName()]['forums_menu'];
+ }
+
+ /* This method stores the menu's status */
+ private function storeMenuSession( $value ) {
+ $_SESSION[game::sessName()]['forums_menu'] = $value;
+ }
+
+ /* This method initialises the main forums session and removes old data */
+ private function initMainSession() {
+
+ if (is_null( $_SESSION[game::sessName()]['forums_data'] )) {
+ $_SESSION[game::sessName()]['forums_data'] = array();
+ return;
+ }
+
+ // Clean up old data
+ $now = time();
+ $nSession = array();
+ foreach ($_SESSION[game::sessName()]['forums_data'] as $key => $data) {
+ if (!is_array( $data )) {
+ continue;
+ }
+ if ($data['ts'] - $now < self::SESSION_TIMEOUT) {
+ $nSession[$key] = $data;
+ }
+ }
+ $_SESSION[game::sessName()]['forums_data'] = $nSession;
+ }
+
+ /* This method is used by specific handlers to read from the session */
+ public function getSessionData($key) {
+ $this->initMainSession();
+ if (is_array($_SESSION[game::sessName()]['forums_data'][$key])
+ && array_key_exists( 'data', $_SESSION[game::sessName()]['forums_data'][$key])) {
+ $_SESSION[game::sessName()]['forums_data'][$key]['ts'] = time();
+ return $_SESSION[game::sessName()]['forums_data'][$key]['data'];
+ }
+ return null;
+ }
+
+ /* This method is used by specific handlers to write into the session */
+ public function setSessionData($key, $data) {
+ $this->initMainSession();
+ $_SESSION[game::sessName()]['forums_data'][$key] = array(
+ "ts" => time(),
+ "data" => $data
+ );
+ }
+
+
+/***********************************************************************************************************************/
+/** MENU HANDLER *******************************************************************************************************/
+/***********************************************************************************************************************/
+
+ /* Returns a boolean indicating whether the menu should be displayed */
+ private function getMenuVisibility() {
+ if (! array_key_exists( 'display_forums_menu', $_SESSION[game::sessName()] )) {
+ $_SESSION[game::sessName()]['display_forums_menu'] = true;
+ }
+ return $_SESSION[game::sessName()]['display_forums_menu'];
+ }
+
+ /* Sets the value for the menu's visibility */
+ private function setMenuVisibility( $value ) {
+ $_SESSION[game::sessName()]['display_forums_menu'] = (boolean) $value;
+ }
+
+ /* This method generates the output for a menu entry */
+ private function makeMenuEntry( &$output, $command, $isLeaf, $isOpen,
+ $displayType, $text, $id = '', $unread = 0 ) {
+
+ // The first line indicates the type of menu entry, as well as the display type,
+ // amount of unread topics and, if the entry is a submenu, whether it's open or not
+ $txt = $isLeaf ? "L" : "N";
+ $txt .= "#$displayType#$unread";
+ if (! $isLeaf) {
+ $txt .= "#" . ($isOpen ? "1" : "0") . "#$id";
+ }
+ array_push( $output, $txt );
+
+ // The two next lines contain the command and text / command ID
+ array_push( $output, $command );
+ array_push( $output, $text );
+ }
+
+ /* This method outputs the "separator" indicator */
+ private function makeMenuSeparator( &$output ) {
+ array_push( $output, "S" );
+ }
+
+ /* This method outputs the "end of menu" indicator */
+ private function makeEndOfMenu( &$output ) {
+ array_push( $output, "E" );
+ }
+
+ /* This method generates the menu's data */
+ private function dumpMenu( &$output, $structure ) {
+
+ // Handle the root of the tree
+ if ($structure instanceof fl_container && $structure->getId() == '/') {
+ // This is the root node
+ $this->makeMenuEntry( &$output, "V#C#/", false, true, "C", "overview", '/' );
+
+ // Add "Latest messages" entry
+ $this->makeMenuEntry( &$output, "L#C#/", true, false, "C", "latest" );
+ // Add the "Search forums" entry
+ $this->makeMenuEntry( &$output, "SF", true, false, "C", "search" );
+
+ // Add the moderation tools submenu
+ // FIXME
+
+ // Add the submenus
+ $this->makeMenuSeparator( &$output );
+ foreach ($structure->getCategories() as $cat) {
+ $this->dumpMenu( &$output, $cat, $menuData );
+ }
+
+ $this->makeEndOfMenu( &$output );
+ return;
+ }
+
+ // Handle containers
+ if ($structure instanceof fl_container) {
+ $id = $structure->getId();
+ $menuData = $this->getMenuSession();
+
+ // Create the node
+ $this->makeMenuEntry( &$output, "V#C#$id", false, $menuData[$id],
+ "T", $structure->getTitle(), $id, $structure->getUnread());
+
+ // Return if the menu's closed
+ if (! $menuData[$id]) {
+ return;
+ }
+
+ // Add "Latest messages" entry
+ $this->makeMenuEntry( &$output, "L#C#$id", true, false, "C", "latest" );
+
+ // Special stuff to be added here
+ // FIXME
+
+ // Add the submenus
+ $catList = $structure->getCategories();
+ if (count($catList)) {
+ $this->makeMenuSeparator( &$output );
+ foreach ($catList as $cat) {
+ $this->dumpMenu( &$output, $cat, $menuData );
+ }
+ }
+
+ $this->makeEndOfMenu( &$output );
+ return;
+ }
+
+ // Standard categories
+ if ($structure instanceof fl_category) {
+ $id = $structure->getId();
+ $menuData = $this->getMenuSession();
+
+ // Create the node
+ $this->makeMenuEntry( &$output, "V#C#$id", false, $menuData[$id],
+ "T", $structure->getTitle(), $id, $structure->getUnread());
+
+ // Return if the menu's closed
+ if (! $menuData[$id]) {
+ return;
+ }
+
+ // Add "Latest messages" entry
+ $this->makeMenuEntry( &$output, "L#C#$id", true, false, "C", "latest" );
+
+ // Special stuff to be added here
+ // FIXME
+
+ // Add the forums
+ $fList = $structure->getForums();
+ if (count($fList)) {
+ $this->makeMenuSeparator( &$output );
+ foreach ($fList as $f) {
+ if ( ! $f->canView() || $f->isDeleted() ) {
+ continue;
+ }
+ $this->makeMenuEntry( &$output, "V#F#" . $f->getId(),
+ true, false, "T", $f->getTitle(), '', $f->getUnread() );
+ }
+ }
+
+ $this->makeEndOfMenu( &$output );
+ return;
+ }
+ }
+
+ /* AJAX method that shows the menu */
+ public function showMenu() {
+ $this->setMenuVisibility(true);
+ return $this->getMenu();
+ }
+
+ /* AJAX method that hides the menu */
+ public function hideMenu() {
+ $this->setMenuVisibility(false);
+ }
+
+ /* AJAX method that returns the forums' menu */
+ public function getMenu($previousMD5 = null) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $this->loadLibraries();
+
+ // Get the forums' structure
+ $structure = input::$game->action('getForums', $pid);
+
+ // Dump the whole thing
+ $result = array();
+ $this->dumpMenu( &$result, $structure );
+
+ // Check the MD5 sum
+ $md5 = md5(serialize($result));
+ if ($md5 !== $previousMD5) {
+ array_unshift($result, $md5);
+ return join("\n", $result);
+ }
+
+ return "-";
+ }
+
+ /* AJAX method that opens a path in the menu */
+ public function menuOpen($toID) {
+ $intID = (int) $toID;
+ if ( in_array($toID, array('G', 'U', 'MT')) || (string) $intID == $toID ) {
+ if ( (string) $intID == $toID ) {
+ $toID = (string) $intID;
+ }
+ $menuData = $this->getMenuSession();
+ $menuData[$toID] = true;
+ $this->storeMenuSession($menuData);
+ }
+
+ return $this->getMenu();
+ }
+
+ /* AJAX method that closes a path in the menu */
+ public function menuClose($toID) {
+ $intID = (int) $toID;
+ if ( in_array($toID, array('G', 'U', 'MT')) || (string) $intID == $toID ) {
+ if ( (string) $intID == $toID ) {
+ $toID = (string) $intID;
+ }
+ $menuData = $this->getMenuSession();
+ $menuData[$toID] = false;
+ $this->storeMenuSession($menuData);
+ }
+
+ return $this->getMenu();
+ }
+
+
+/***********************************************************************************************************************/
+/** CATEGORY / FORUM VIEW **********************************************************************************************/
+/***********************************************************************************************************************/
+
+ /* AJAX method used to refresh a view page */
+ public function getView($whichView, $md5) {
+ $handler = input::$game->getLib('beta5/forums/view');
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler->call('forumCommand', $pid, $whichView);
+ return $handler->call('getData', $md5);
+ }
+
+ /* AJAX method that marks all of a category's forums as read */
+ public function categoryRead($category, $whichView) {
+ $handler = input::$game->getLib('beta5/forums/view');
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler->call('forumCommand', $pid, $whichView);
+ $handler->call('categoryRead', $category);
+ return $handler->call('getData', $md5);
+ }
+
+ /* AJAX method that set forums options */
+ public function forumOptions($forum, $toAll, $perPage, $viewDeleted, $md5) {
+ $forum = (int) $forum;
+ $toAll = ($toAll == '1');
+ $perPage = ($perPage > 0 && $perPage % 10 == 0 && $perPage / 10 < 6) ? (int)$perPage : 20;
+ $viewDeleted = $viewDeleted;
+ $pid = $_SESSION[game::sessName()]['player'];
+
+ $this->loadLibraries();
+ $this->forums->call('setOptions', $pid, $toAll ? -1 : $forum, $perPage, $viewDeleted);
+
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ return $handler->call('getData', $md5);
+ }
+
+ /* AJAX method that set forums options */
+ public function forumRead($forum) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('forumRead');
+ return $handler->call('getData');
+ }
+
+ /* AJAX method that restores a set of topics */
+ public function restoreTopics($forum, $topics) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('restoreTopics', explode('#', $topics));
+ return $handler->call('getData');
+ }
+
+ /* AJAX method that deletes a set of topics */
+ public function deleteTopics($forum, $topics) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('deleteTopics', explode('#', $topics));
+ return $handler->call('getData');
+ }
+
+ /* AJAX method that changes the sticky level for a set of topics */
+ public function changeTopicsLevel($forum, $topics, $change) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('changeTopicsLevel', explode('#', $topics), $change);
+ return $handler->call('getData');
+ }
+
+ /* AJAX method that sets the sticky level for a set of topics */
+ public function setTopicsLevel($forum, $topics, $level) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('setTopicsLevel', explode('#', $topics), $level);
+ return $handler->call('getData');
+ }
+
+ /* AJAX method that sets the lock for a set of topics */
+ public function setTopicsLock($forum, $topics, $lock) {
+ $lock = ($lock == '1');
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('setTopicsLock', explode('#', $topics), $lock);
+ return $handler->call('getData');
+ }
+
+ /* AJAX method that moves a set of topics to another forum */
+ public function moveTopics($forum, $topics, $destination) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/view');
+ $handler->call('forumCommand', $pid, "F#$forum");
+ $handler->call('moveTopics', explode('#', $topics), $destination);
+ return $handler->call('getData');
+ }
+
+
+/***********************************************************************************************************************/
+/** TOPIC VIEW *********************************************************************************************************/
+/***********************************************************************************************************************/
+
+ /* AJAX method that returns a post's contents */
+ public function loadPostContents($topic, $md5, $postId) {
+ $pid = $_SESSION[game::sessName()]['player'];
+ $handler = input::$game->getLib('beta5/forums/topic');
+ $handler->call('initialize', $this);
+ $handler->call('forumCommand', $pid, "$topic#$md5");
+ return $handler->call('getPostContents', $postId);
+ }
+
+
+/***********************************************************************************************************************/
+/** PAGE HANDLER *******************************************************************************************************/
+/***********************************************************************************************************************/
+
+ /* The main page handler */
+ public function handle($input) {
+
+ // Get the command
+ $cmd = $input['cmd'];
+ if ($cmd == 'o' || $cmd == '') {
+ $cmd = 'V#C#/';
+ }
+
+ // Check the command
+ if ($cmd == 'SF') {
+ // Search forums
+ $args = array(); // FIXME
+ } elseif ($cmd == 'xx') {
+ // FIXME: other 'simple' commands
+ } else {
+ $rCmd = $cmd{0};
+ $args = substr($cmd, 2);
+ if ($rCmd == 'V') {
+ // View command
+ $handler = input::$game->getLib('beta5/forums/view');
+ } elseif ($rCmd == 'T') {
+ // View topic command
+ $handler = input::$game->getLib('beta5/forums/topic');
+ }
+ }
+
+ // Execute the command
+ $handler->call('initialize', $this);
+ list($mCurrent, $pageType, $pageData) = $handler->call( 'forumCommand',
+ $_SESSION[game::sessName()]['player'], $args );
+
+ $this->data = array(
+ "needData" => input::$IE,
+ "showMenu" => $this->getMenuVisibility(),
+ "menuCurrent" => $mCurrent,
+ "pageType" => $pageType
+ );
+ if (input::$IE) {
+ $this->data['menuContents'] = '';
+ $this->data['pageData'] = $pageData;
+ } else {
+ if ($this->data['showMenu']) {
+ $this->data['menuContents'] = $this->getMenu();
+ }
+ $this->data['pageData'] = $handler->call('getData');
+ }
+
+ $this->output = "forums";
+ }
+
}
?>
diff -Naur beta5//scripts/site/beta5/output/comms.en.inc forums//scripts/site/beta5/output/comms.en.inc
--- beta5//scripts/site/beta5/output/comms.en.inc 2011-02-05 10:09:57.294335002 +0100
+++ forums//scripts/site/beta5/output/comms.en.inc 2011-03-12 14:56:19.761300052 +0100
@@ -15,9 +15,7 @@
Forums
- General forums
-
-
+
Help
diff -Naur beta5//scripts/site/beta5/output/forums.en.inc forums//scripts/site/beta5/output/forums.en.inc
--- beta5//scripts/site/beta5/output/forums.en.inc 2011-02-05 10:09:57.294335002 +0100
+++ forums//scripts/site/beta5/output/forums.en.inc 2011-02-05 10:10:02.974335002 +0100
@@ -1,5 +1,6 @@
+/*
function drawForumsMenu($mode,$fList)
{
?>
@@ -68,5 +69,19 @@
$sp = $args['sp'];
$args = $args['d'];
include("forums/en/$sp.inc");
+*/
?>
+
+
=$args['showMenu'] ? 1 : 0?>#=$args['needData'] ? 1 : 0?>#=$args['pageType']?>
+
+
+
+
=$args['pageData']?>
+
+
+
diff -Naur beta5//scripts/ticks.php forums//scripts/ticks.php
--- beta5//scripts/ticks.php 2011-02-05 10:09:57.904335002 +0100
+++ forums//scripts/ticks.php 2011-03-12 15:13:57.671300053 +0100
@@ -20,8 +20,8 @@
$__loader = array(
'log', 'classloader',
'version', 'game', 'tick', 'config',
- 'db_connection', 'db_accessor', 'db_copy', 'db',
- 'pcheck', 'library', 'tick_manager',
+ 'db_connection', 'db_accessor', 'db_copy' , 'db_query',
+ 'db', 'pcheck' , 'library', 'tick_manager',
);
require_once("loader.inc");
diff -Naur beta5//site/index.php forums//site/index.php
--- beta5//site/index.php 2011-02-05 10:09:57.164335002 +0100
+++ forums//site/index.php 2011-02-05 10:10:02.844335002 +0100
@@ -4,8 +4,8 @@
$__loader = array(
'log', 'classloader',
'version', 'game', 'tick', 'config',
- 'db_connection', 'db_accessor', 'db',
- 'library', 'actions', 'data_tree',
+ 'db_connection', 'db_accessor', 'db_query',
+ 'db', 'library', 'actions', 'data_tree',
'input', 'ajax', 'handler', 'engine',
'resource', 'tracking', 'session',
'account', 'prefs', 'output'
diff -Naur beta5//site/static/beta5/js/pg_alliance-en.js forums//site/static/beta5/js/pg_alliance-en.js
--- beta5//site/static/beta5/js/pg_alliance-en.js 2011-02-05 10:09:56.434335002 +0100
+++ forums//site/static/beta5/js/pg_alliance-en.js 2011-03-12 15:12:38.321300050 +0100
@@ -1037,54 +1037,105 @@
// FORUMS ADMINISTRATION PAGE
//--------------------------------------------------
-function drawForumList()
-{
+function drawForumList() {
var str = '';
str += 'Alliance Forums ';
str += '
';
document.getElementById('alpmain').innerHTML = str;
- if (faForums.length < 30)
- drawCreateForumLink();
- if (faForums.length == 0)
+
+ if (faForums.length < 30) {
+ document.getElementById('crforum').innerHTML = 'Create a forum ';
+ }
+
+ if (faForums.length == 0) {
drawTextNoForums();
- else
+ } else {
drawRealForumList();
+ }
}
-function drawCreateForumLink()
-{
- var str = '';
- str += 'Create a forum ';
- document.getElementById('crforum').innerHTML = str;
-}
-
-function drawTextNoForums()
-{
+function drawTextNoForums() {
document.getElementById('falist').innerHTML = 'No forums have been defined for the alliance.
';
}
-function drawRealForumList()
-{
- var i, str = '';
+function drawRealForumList() {
+ var i, str = '';
+
+ var getFRankText = function (id) {
+ var r = faRanks['r' + id];
+ return r == '-' ? 'Default member ' : r;
+ }
+
+ str += 'Name & description User access mode ';
+ for (i = 0; i < faForums.length; i++) {
+ str += ''
+ + faForums[i].name.replace(/&/g, '&').replace(//g, '>')
+ + ' (';
+ if (faForums[i].isDeleted) {
+ str += 'deleted by ' + faPlayers['p' + faForums[i].deletedBy] + ' at '
+ + formatDate(faForums[i].deletedAt) + ' - Restore ';
+ } else {
+ str += 'Edit - ';
+ if (i > 0) {
+ str += 'Move up - ';
+ }
+ if (i < faForums.length - 1) {
+ str += 'Move down - ';
+ }
+ str += 'Delete ';
+ }
+ str += ")";
+
+ if (faForums[i].description != '' || faForums[i].users.length || faForums[i].mods.length) {
+
+ var nbr = false;
+ str += '';
+
+ if (faForums[i].description != '') {
+ str += faForums[i].description.replace(/&/g, '&').replace(//g, '>').replace(/\n/g," ");
+ nbr = true;
+ }
+
+ if (faForums[i].users.length) {
+ str += (nbr ? ' ' : '') + 'Users: ';
+ for (var ri in faForums[i].users) {
+ str += (ri > 0 ? ' - ' : '') + getFRankText(faForums[i].users[ri]);
+ }
+ nbr = true;
+ }
+
+ if (faForums[i].mods.length) {
+ str += (nbr ? ' ' : '') + 'Moderators: ';
+ for (var ri in faForums[i].mods) {
+ str += (ri > 0 ? ' - ' : '') + getFRankText(faForums[i].mods[ri]);
+ }
+ nbr = true;
+ }
+
+ str += '
';
+ }
- str += 'Name & description New threads ';
- for (i=0;i';
- str += '' + faForums[i].name.replace(/&/g, '&').replace(//g, '>') + ' (';
- str += 'Edit - ';
- if (i > 0)
- str += 'Move up - ';
- if (i < faForums.length - 1)
- str += 'Move down - ';
- str += 'Delete )';
- if (faForums[i].description != '')
- str += '' + faForums[i].description.replace(/&/g, '&').replace(//g, '>').replace(/\n/g," ") + '
';
str += '';
- if (faForums[i].userPost)
- str += 'Everyone';
- else
- str += 'Moderators only';
+ switch (faForums[i].accessMode) {
+ case 'L':
+ str += 'Full access';
+ break;
+ case 'T':
+ str += 'No polls';
+ break;
+ case 'P':
+ str += 'Replies only';
+ break;
+ case 'M':
+ str += 'Read only';
+ break;
+ }
str += ' ';
}
@@ -1092,85 +1143,96 @@
document.getElementById('falist').innerHTML = str;
}
-function cheatAlert()
-{
- alert('Possible cheating detected.');
-}
-
-function confirmDeleteForum(name)
-{
- var str = 'You are about to delete the following forum:\n' + name + '\n';
- str += 'The forum\'s topics will be lost and you will not be able to recover them.\nPlease confirm.';
+function confirmDeleteForum(forum) {
+ var str = 'You are about to delete the following forum:\n ' + forum.name + '\n';
+ if (forum.topics > 0) {
+ str += 'The forum contains '
+ + (forum.topics > 1 ? (formatNumber(forum.topics.toString()) + ' topics') : 'a single topic')
+ + '.\n';
+ }
+ str += 'Please confirm.';
return confirm(str);
}
-function alertMaximumFCount()
-{
+function alertMaximumFCount() {
alert('The alliance has reached its maximum possible count of forums.\nYou will be taken back to the list.');
}
-function drawForumEditor()
-{
+function drawForumEditor() {
document.getElementById('falist').innerHTML = ' ';
var str;
- if (faEditing.id)
- {
+ if (faEditing.id) {
f = forumById(faEditing.id);
str = "'" + f.name.replace(/&/g, '&').replace(//g, '>') + "' forum";
- }
- else
+ } else {
str = "Create a forum";
+ }
document.getElementById('fattl').innerHTML = '' + str + ' ';
- str = '';
document.getElementById('falist').innerHTML = str;
+
+ document.getElementById('fname').value = faEditing.name;
+ document.getElementById('fdesc').value = faEditing.description;
document.getElementById('feok').disabled = true;
- if (!faEditing.id)
+ if (!faEditing.id) {
updateFPosSelector();
+ }
+ drawFAccessManager();
}
-function updateFPosSelector()
-{
- var i, str = '';
- str += 'At the beginning ';
- for (i=0;iAt the beginning';
+ for (i = 0; i < faForums.length; i ++) {
str += 'After ' + faForums[i].name + ' ';
}
str += ' ';
document.getElementById('faeipos').innerHTML = str;
}
-function drawFAccessManager()
-{
+function drawFAccessManager() {
var lnp = new Array(), lmd = new Array(), lrd = new Array(), ml, i, sc=0;
for (i=0;i 0 ? "\n" : "") + lines.shift();
+ }
+
+ return this;
+ };
+
+ this.copyFrom = function (ori) {
+ this.id = ori.id;
+ this.isDeleted = ori.isDeleted;
+ this.deletedBy = ori.deletedBy;
+ this.deletedAt = ori.deletedAt;
+ this.accessMode = ori.accessMode;
+ this.topics = ori.topics;
+ this.name = ori.name;
+ this.description = ori.description
+
+ // Users
+ for (var i in ori.users) {
+ this.users.push(ori.users[i]);
+ }
+
+ // Moderators
+ for (var i in ori.mods) {
+ this.mods.push(ori.users[i]);
+ }
+
+ return this;
+ };
}
-function ForumACL(id,priv,name)
-{
+
+function ForumACL(id, priv, name) {
this.id = id;
this.priv = priv;
this.name = name;
this.selected = false;
}
+
function forumsReceived(data) {
if (amPage != 'FAdmin') {
return;
}
- faForums = new Array();
if (data.indexOf("ERR#") == 0) {
- alertForum(parseInt((data.split('#'))[1], 10));
- puTimer = setTimeout('x_getForums(forumsReceived)', 180000);
- return;
- } else if (data != "") {
- parseForumList(data);
+ var lines = data.split('\n');
+ var el = lines.shift();
+ data = lines.join('\n');
+
+ alertForum(parseInt((el.split('#'))[1], 10));
}
+ parseForumList(data);
if (!faEditing) {
drawForumList();
@@ -1292,15 +1354,19 @@
alertMaximumFCount();
forumEditCancel();
} else if (!faEditing.id) {
- if (faNewPos != -1 && !forumById(faNewPos))
+ if (faNewPos != -1 && !forumById(faNewPos)) {
faNewPos = -1;
+ }
updateFPosSelector();
} else if (faEditing.id) {
- var f = forumById(faEditing.id);
- if (!f) {
+ var f = forumById(faEditing.id);
+ if (!f || f.isDeleted) {
alertForumDeleted();
forumEditCancel();
- } else if (faOriginal.name != f.name || faOriginal.userPost != f.userPost || faOriginal.description != f.description) {
+ } else if (faOriginal.name != f.name
+ || faOriginal.accessMode != f.accessMode
+ || faOriginal.description != f.description) {
+
alertForumChanged();
updateFEditor();
} else {
@@ -1310,111 +1376,119 @@
puTimer = setTimeout('x_getForums(forumsReceived)', 180000);
}
-function parseForumList(data)
-{
- var dl = data.split('\n');
- var st = 0, i = 0, cf = 0;
- var a;
- while (i b.order ? 1 : -1)'));
+ i = lines.shift();
+ faAdmins = (i == '') ? (new Array()) : i.split('#');
+
+ var pCount = parseInt(lines.shift(), 10);
+ faPlayers = { };
+ for (i = 0; i < pCount; i ++) {
+ var rLine = lines.shift().split('#');
+ faPlayers['p' + rLine.shift()] = rLine.join('#');
+ }
}
-function moveForum(id,up)
-{
+
+function moveForum(id, up) {
x_moveForum(id, up ? 1 : 0, forumsReceived);
}
-function forumById(id)
-{
- var i;
- for (i=0;i b.name.toLowerCase() ? 1 : -1'));
+ faAccess.push(new ForumACL(rId, pr, rn));
}
- if (faEditing.id)
+ faAccess.sort(new Function('a','b','return a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1'));
+
+ if (faEditing.id) {
faOriACL = makeForumACLString();
- drawFAccessManager();
- updateFEditor();
+ }
}
+
function setFAccessLevel(level)
{
var i,cc=0;
@@ -1432,33 +1506,36 @@
}
}
-function updateFEditor()
-{
- var ok, i;
+function updateFEditor() {
+ var ok, i;
ok = (faEditing.name.length >= 4);
- if (faEditing.id)
+ if (faEditing.id) {
ok = ok && (
faEditing.name != faOriginal.name || faEditing.description != faOriginal.description
- || faEditing.userPost != faOriginal.userPost || faOriACL != makeForumACLString()
+ || faEditing.accessMode != faOriginal.accessMode || faOriACL != makeForumACLString()
);
+ }
document.getElementById('feok').disabled = !ok;
}
-function makeForumACLString()
-{
- var a = new Array(), i;
- for (i=0;i topic' + (tot > 1 ? 's' : '');
- if (n == 0)
- return str;
- str += ' (' + formatNumber(n) + ' unread)';
- return str;
+function makeTopicsText(tot, n) {
+ if (tot == 0) {
+ return "empty forum";
+ }
+
+ var str = '' + formatNumber(tot.toString()) + ' topic' + (tot > 1 ? 's' : '');
+ if (n == 0) {
+ return str;
+ }
+ str += ' (' + formatNumber(n.toString()) + ' unread)';
+ return str;
}
diff -Naur beta5//site/static/beta5/js/pg_comms.js forums//site/static/beta5/js/pg_comms.js
--- beta5//site/static/beta5/js/pg_comms.js 2011-02-05 10:09:56.434335002 +0100
+++ forums//site/static/beta5/js/pg_comms.js 2011-03-12 15:09:43.961300049 +0100
@@ -12,20 +12,40 @@
this.name = name;
}
-function Category(id, type, name)
-{
- this.id = id;
- this.type = type;
- this.name = name;
- this.forums = new Array();
-}
-function Forum(id, nTopics, nUnread, name)
-{
- this.id = id;
- this.nTopics = nTopics;
- this.nUnread = nUnread;
- this.name = name;
+
+function ForumsEntity(inputData) {
+ var iLine = inputData.shift().split('#');
+ var nElements;
+
+ this.type = iLine.shift();
+ this.id = iLine.shift();
+ nElements = parseInt(iLine.shift(), 10);
+ this.topics = parseInt(iLine.shift(), 10);
+ this.unread = parseInt(iLine.shift(), 10);
+ this.name = inputData.shift();
+ this.contents = new Array();
+ this.output = function (depth) {
+ var str = '';
+
+ if (this.id != '/') {
+ for (var i = 0; i < depth; i++) {
+ str += ' ';
+ }
+ str += '' + this.name + ' : '
+ + makeTopicsText(this.topics, this.unread);
+ }
+
+ for (var i = 0; i < this.contents.length; i ++) {
+ str += ' ' + this.contents[i].output(depth + 1);
+ }
+
+ return str;
+ };
+
+ for (var i = 0; i < nElements; i ++) {
+ this.contents.push( new ForumsEntity(inputData) );
+ }
}
@@ -35,110 +55,55 @@
}
-function commsDataReceived(data)
-{
- var i, l = data.split('\n');
- var a = l.shift().split('#');
- var nCustom = parseInt(a[0],10), nGenCats = parseInt(a[1],10), nAForums = parseInt(a[2],10);
+function commsDataReceived(data) {
+ var i, a, nCustom;
+ var l = data.split('\n');
// Default folders
dFolders = new Array();
- for (i=0;i<3;i++)
- {
+ for (i=0;i<3;i++) {
a = l.shift().split('#');
dFolders.push(new Folder('', a[0], a[1], ''));
}
// Custom folders
+ nCustom = parseInt(l.shift(), 10);
cFolders = new Array();
- for (i=0;i' + cFolders[i].name + ': ' + makeMessagesText(cFolders[i].tMsg, cFolders[i].nMsg);
+ for (i=0;i' + cFolders[i].name + ': '
+ + makeMessagesText(cFolders[i].tMsg, cFolders[i].nMsg);
a.push(s);
}
document.getElementById('cflist').innerHTML = a.join(' ') + ' ';
}
- // General forums
- a = new Array();
- for (i=0;i' + name + '';
- for (j=0;j - ' + forums[j].name + ' : ';
- s += makeTopicsText(forums[j].nTopics, forums[j].nUnread);
- }
- a.push(s);
- }}
- document.getElementById('gforums').innerHTML = a.join(' ');
-
- // Alliance forums
- if (aForums.length == 0)
- document.getElementById('aforums').innerHTML = ' ';
- else
- {
- a = new Array();
- for (j=0;j' + aForums[j].name + ': ';
- s += makeTopicsText(aForums[j].nTopics, aForums[j].nUnread);
- a.push(s);
- }
- document.getElementById('aforums').innerHTML = '' + allianceForums + ' ' + a.join(' ') + '
';
- }
+ // Forums
+ document.getElementById('forums').innerHTML = '' + forums.output(-1) + '
';
}
diff -Naur beta5//site/static/beta5/js/pg_forums-en.js forums//site/static/beta5/js/pg_forums-en.js
--- beta5//site/static/beta5/js/pg_forums-en.js 2011-02-05 10:09:56.434335002 +0100
+++ forums//site/static/beta5/js/pg_forums-en.js 2011-02-05 10:10:02.214335002 +0100
@@ -1,53 +1,98 @@
-function confirmDelete()
-{
- var i = countSelected();
- if (i == 0)
- {
- alert('Please select the topic(s) you want to delete.');
- return false;
- }
- return confirm('Please confirm you want to delete ' + (i > 1 ? ('these ' + i + ' topics') : 'this topic') + '.');
-}
-
-function confirmSticky()
-{
- var i = countSelected();
- if (i == 0)
- {
- alert('Please select the topic(s) you want to switch to/from sticky.');
- return false;
- }
- return confirm('Please confirm you want to switch ' + (i > 1 ? ('these ' + i + ' topics') : 'this topic') + ' to/from sticky.');
-}
-
-function confirmMove()
-{
- var i = countSelected();
- if (i == 0)
- {
- alert('Please select the topic(s) you want to move.');
- return false;
- }
-
- var e = document.getElementById('mdest');
- if (e.options[e.selectedIndex].value == '')
- {
- alert('Please select the forum to which the topic'+(i>1?'s':'')+' must be moved.');
- return false;
- }
-
- return confirm(
- 'Please confirm you want to move the selected topic' + (i>1?'s':'') + '\nto the "'
- + e.options[e.selectedIndex].text + '" forum.'
- );
-}
-
-function confirmDTopic()
-{
- return confirm('Deleting this post will delete the whole topic. Please confirm.');
-}
-
-function confirmDPost()
-{
- return confirm('Please confirm you want to delete this post.');
-}
+/* Text for menu commands */
+MenuItem.commandText = {
+ overview: "Overview",
+ latest: "Latest messages",
+ search: "Search forums"
+};
+
+/* Overview pseudo-category title & description */
+CategoryView.ovTitle = "Forums overview";
+CategoryView.ovDescription = "This page gives you a global view of all of the forums you have access to.";
+
+/* Text for layout-level commands */
+ForumsLayout.menuText = ['S','h','o','w',' ','m','e','n','u'];
+ForumsLayout.hideMenu = "Hide";
+ForumsLayout.menuTitle = "Forums";
+
+/* Text for the category view */
+CategoryView.empty = 'There are no forums in this category.';
+CategoryView.headers = {
+ name: 'Forum name',
+ topics: 'Topics',
+ posts: 'Posts',
+ lastPost: 'Last modification'
+};
+CategoryView.forumIcon = {
+ read: "This forums's topics have been read",
+ unread: "Some topics in this forum haven't been read"
+};
+CategoryView.deletedAt = "Forum deleted at ";
+CategoryView.by = " by ";
+CategoryView.noPosts = 'Empty forum';
+CategoryView.markRead = 'Mark forums as read';
+
+/* Text for the forum view */
+ForumView.markRead = 'Mark topics as read';
+ForumView.adminsHdr = 'Administrators';
+ForumView.modsHdr = 'Moderators';
+ForumView.usersHdr = 'Users';
+ForumView.empty = 'There are no topics in this forum.';
+ForumView.details = ' More details ... ';
+ForumView.showDetails = 'Show details';
+ForumView.hideDetails = 'Hide details';
+ForumView.displayOptions = 'Display options';
+ForumView.newTopic = 'New topic';
+ForumView.modTools = 'Moderation tools';
+ForumView.previousPage = 'Previous page';
+ForumView.nextPage = 'Next page';
+ForumView.pageSelHdr = 'Jump to page ';
+ForumView.headers = {
+ topic: 'Topic',
+ replies: 'Replies',
+ fPost: 'First post',
+ lPost: 'Last update'
+};
+ForumView.movedTo = 'Moved to ';
+ForumView.applyTo = 'Apply to ';
+ForumView.thisForum = 'this forum';
+ForumView.allForums = 'all forums';
+ForumView.perPage = 'Topics / page:';
+ForumView.ok = 'Ok';
+ForumView.cancel = 'Cancel';
+ForumView.displayDeleted = 'Display deleted topics:';
+ForumView.deletedAt = 'Topic deleted at ';
+ForumView.hideModTools = 'Hide moderation tools';
+ForumView.pleaseSelect = 'Please select at least one topic.';
+ForumView.deletedTopics = 'Deleted topics: ';
+ForumView.restoreTopics = 'restore';
+ForumView.selectedTopics = 'Selected topics: ';
+ForumView.deleteTopics = 'delete';
+ForumView.stickyLevel = 'sticky level: ';
+ForumView.decreaseStickyLevel = 'decrease';
+ForumView.increaseStickyLevel = 'increase';
+ForumView.setTo = 'set to ';
+ForumView.normalPost = 'not sticky';
+ForumView.lock = 'lock';
+ForumView.unlock = 'unlock';
+ForumView.moveTo = 'Move topics to ';
+
+
+/* Topic view: topic not found */
+TopicView.notFound = {
+ title: "Topic not found",
+ text: "The topic you were looking for is unavailable, either because it doesn't exist anymore or "
+ + "because you don't have access to the forum it is in."
+};
+/* Topic view: deleted topic */
+TopicView.deleted = {
+ header: "This topic was deleted at ",
+ by: " by "
+};
+/* Topic view: show / hide post contents */
+TopicView.close = "Hide post contents";
+TopicView.open = "Show post contents";
+/* Topic view, misc text */
+TopicView.posted = "Posted ";
+TopicView.loading = "Loading, please wait ...";
+TopicView.loadError = "An error occurred while loading this post :-(";
+TopicView.edited = "Edited at ";
diff -Naur beta5//site/static/beta5/js/pg_forums.js forums//site/static/beta5/js/pg_forums.js
--- beta5//site/static/beta5/js/pg_forums.js 2011-02-05 10:09:56.434335002 +0100
+++ forums//site/static/beta5/js/pg_forums.js 2011-02-05 10:10:02.204335002 +0100
@@ -1,10 +1,1607 @@
-function countSelected()
-{
- var n = 0, i = 0, e;
- while (e = document.getElementById('msel' + i))
- {
- n += e.checked ? 1 : 0;
- i++;
+var pageContents;
+var useGIFs;
+
+
+MenuItem = function (lines) {
+
+ // Parse the data
+ var fields = lines.shift().split('#');
+
+ this.isNode = (fields.shift() == 'N');
+ this.isCommand = (fields.shift() == 'C');
+ this.unread = parseInt(fields.shift(), 10);
+ this.isOpen = this.isNode ? (fields.shift() == '1') : false;
+ this.id = this.isNode ? fields.shift() : null;
+ this.cmdLink = lines.shift();
+ this.text = lines.shift();
+ this.entries = (this.isNode && this.isOpen) ? (new Array()) : null;
+
+ if (this.isCommand) {
+ this.text = MenuItem.commandText[this.text];
}
- return n;
-}
+
+ // Add menu entries
+ while (this.isNode && this.isOpen && lines[0] != 'E') {
+ if (lines[0] == 'S') {
+ // Separators
+ this.entries.push(null);
+ lines.shift();
+ } else {
+ // Entries
+ this.entries.push(new MenuItem(lines));
+ }
+ }
+ if (this.isNode && this.isOpen) {
+ lines.shift();
+ }
+
+ this.draw = function (output, depth) {
+ var rd = (typeof depth == 'undefined') ? -1 : depth;
+
+ var cst = ' style="margin: 0px; padding: 0px; border-width: 0px; vertical-align: middle"';
+ var tst = ' style="width: 100%; margin: 0px; padding: 0px; border-width: 0px"';
+ var smallCell = '';
+ var str = ' ';
+
+ // Output this line
+ output.push(str);
+
+ // Submenus
+ var sepPrev = false;
+ for (var i in this.entries) {
+ var e = this.entries[i];
+ if (e) {
+ if (e.isNode && e.isOpen && !sepPrev) {
+ output.push(' ');
+ }
+ e.draw(output, rd + 1);
+ if (e.isNode && e.isOpen) {
+ output.push(' ');
+ sepPrev = true;
+ } else {
+ sepPrev = false;
+ }
+ } else if (!sepPrev) {
+ output.push(' ');
+ sepPrev = true;
+ }
+ }
+ };
+};
+
+
+function parseNames( lines ) {
+ var line, cnt;
+ var res = { };
+
+ cnt = parseInt( lines.shift(), 10 );
+ for (var i = 0; i < cnt; i ++) {
+ line = lines.shift().split('#');
+ res[line[0]] = line[1];
+ }
+
+ return res;
+};
+
+
+TopicView = function () {
+
+ var me = this;
+ var tst = ' style="width: 100%; margin: 0px; padding: 0px; border-width: 0px"';
+ var cst = ' style="margin: 0px; padding: 0px; border-width: 0px; vertical-align: middle';
+
+ var pageUpdater = null;
+ var pageMD5 = null;
+ var topicId = null;
+ var locked = false;
+ var parents = [];
+ var posts = [];
+ var pOrder = {
+ ln: null,
+ lo: null,
+ tn: null,
+ to: null
+ };
+ var opts = {
+ perPage: 50,
+ vDeleted: false,
+ threaded: false,
+ order: false,
+ openPosts: 1
+ };
+ var title;
+ var topicStatus;
+ var currentUser;
+ var isMod;
+ var canPost;
+ var hasPoll;
+ var users;
+ var nPages;
+ var cPage;
+ var queue;
+
+ var parseInitialContents, displayNotFound, displayDeleted, displayTopicLayout, drawPageChanger,
+ displayPage, initLoaderQueue, loadPost, postLoaded;
+
+ parseInitialContents = function (data) {
+ var line = data.shift();
+
+ if (line == 'MEH') {
+ displayNotFound();
+ return false;
+ }
+
+ if (line.indexOf('DELETED#') == 0) {
+ var deletedAt, nParents;
+ line = line.split('#');
+ deletedAt = line[1];
+ nParents = parseInt(line[2], 10);
+ displayDeleted(data, deletedAt, nParents);
+ return false;
+ }
+
+ line = line.split('#');
+ var nParents = parseInt(line[1], 10);
+
+ title = data.shift();
+ line = data.shift().split('#');
+ currentUser = line.shift();
+ isMod = (line.shift() == 1);
+ canPost = (line.shift() == 1);
+ hasPoll = (line.shift() == 1);
+
+ for (var i = 0; i < nParents; i ++) {
+ line = data.shift().split('#');
+ parents.push({
+ id: line.shift(),
+ name: line.join('')
+ });
+ }
+
+ pOrder.ln = data.shift().split('#');
+ pOrder.lo = data.shift().split('#');
+ pOrder.tn = data.shift().split('#');
+ pOrder.to = data.shift().split('#');
+
+ for (var i = 0; i < pOrder.ln.length; i ++) {
+ var p = { };
+ line = data.shift().split('#');
+ p.id = line.shift();
+ p.depth = parseInt(line.shift(), 10);
+ p.author = line.shift();
+ p.postedAt = line.shift();
+ p.unread = (line.shift() == 1);
+ p.lcTime = line.shift();
+ p.lcAuthor = line.shift();
+ p.title = data.shift();
+ p.loading = false;
+ posts[p.id] = p;
+ }
+
+ users = parseNames( data );
+
+ line = data.shift().split('#');
+ opts.perPage = parseInt(line.shift(), 10);
+ opts.vDeleted = (line.shift() == 1);
+ opts.threaded = (line.shift() == 1);
+ opts.order = (line.shift() == 1);
+ opts.openPosts = parseInt(line.shift(), 10);
+
+ for (var i in posts) {
+ switch (opts.openPosts) {
+ case 0: posts[i].open = false;
+ break;
+ case 1: posts[i].open = posts[i].unread;
+ break;
+ case 2: posts[i].open = true;
+ break;
+ }
+ }
+
+ initLoaderQueue();
+
+ var m = pOrder.ln.length % opts.perPage;
+ nPages = (pOrder.ln.length - m) / opts.perPage + (m ? 1 : 0);
+ cPage = 0;
+ displayTopicLayout();
+ };
+
+ displayNotFound = function () {
+ document.getElementById('f-page').innerHTML = '' + TopicView.notFound.title + ' '
+ + TopicView.notFound.text + '
';
+ };
+
+ displayDeleted = function (data, deletedAt, nParents) {
+ var str = '' + TopicView.deleted.header + '' + formatDate(deletedAt)
+ + ' ' + TopicView.deleted.by + ''
+ + 'some guy (FIXME)' + ' .
';
+ document.getElementById('f-page').innerHTML = str;
+ };
+
+ displayTopicLayout = function () {
+ var str = ''
+ + title + ' ';
+ for (var i in parents) {
+ str += (i > 0 ? ' > ' : '') + '
'
+ + (parents[i].id == '/' ? ForumsLayout.menuTitle : parents[i].name) + ' ';
+ }
+
+ str += '
';
+ str += drawPageChanger();
+
+ // FIXME: display tools
+
+ if (hasPoll) {
+ // FIXME: display poll
+ }
+
+ str += ' ';
+ str += drawPageChanger();
+ str += '
';
+
+ document.getElementById('f-page').innerHTML = str;
+ displayPage();
+ };
+
+ drawPageChanger = function () {
+ if (nPages > 1) {
+ var st = 'border-width: 0px; margin: 0px; vertical-align: middle; ';
+ var str = '
'
+ + (cPage > 0 ? '' : '')
+ + '<-- ' + ForumView.previousPage + (cPage > 0 ? ' ' : '')
+ + ' '
+ + ' '
+ + ((cPage' : '')
+ + ForumView.nextPage + '-->' + ((cPage' : '') + ' ';
+ return str;
+ }
+ return '';
+ };
+
+ displayPage = function () {
+ var low = cPage * opts.perPage;
+ var high = Math.min(low + opts.perPage, pOrder.ln.length);
+ var str = '\n\n
';
+ var order;
+
+ if (opts.threaded) {
+ order = opts.order ? pOrder.to : pOrder.tn;
+ } else {
+ order = opts.order ? pOrder.lo : pOrder.ln;
+ }
+
+ for (var i = low; i < high; i ++) {
+ var post = posts[order[i]];
+ str += '\n';
+ if (opts.threaded && post.depth > 0) {
+ var sz = post.depth * 10;
+ str += ' ';
+ }
+ str += ' 
';
+ }
+ document.getElementById('topics-display').innerHTML = str + '\n
';
+
+ displayPosts();
+ };
+
+ displayPosts = function () {
+ for (var i in posts) {
+ var post = posts[i];
+ var el = document.getElementById("tp-post-" + post.id);
+ if (el) {
+ el.innerHTML = displayPost(post);
+ }
+ }
+ };
+
+ displayPost = function (post) {
+ var color = post.unread ? '#FFFFFF' : '#5F5F5F';
+ var margin = post.open ? (post.depth == 0 ? '0px 0px 10px 0px' : '10px 0px') : '0px';
+ var onClick = ' onClick="pageContents.togglePost(' + post.id + ')"';
+ var str = '
'
+ + ''
+ + post.title + ' ' + TopicView.posted + '' + formatDate(post.postedAt) + ' '
+ + CategoryView.by + '' + users[post.author] + ' ';
+
+ if (post.open) {
+ str += ''
+ + (post.loaded ? post.contents :
+ ('' + TopicView.loading + '
'))
+ + ' ';
+ if (post.lcTime != post.postedAt) {
+ str += '' + TopicView.edited
+ + formatDate(post.lcTime) + CategoryView.by + ''
+ + users[post.lcAuthor] + ' ';
+ }
+ }
+
+ return str + '
';
+ };
+
+ initLoaderQueue = function () {
+ var order;
+
+ if (opts.threaded) {
+ order = opts.order ? pOrder.to : pOrder.tn;
+ } else {
+ order = opts.order ? pOrder.lo : pOrder.ln;
+ }
+
+ var openPosts = [], fpPosts = [], rest = [];
+ for (var i in order) {
+ var post = posts[order[i]];
+ if (post.open) {
+ openPosts.push(post);
+ } else if (i < opts.perPage) {
+ fpPosts.push(post);
+ } else {
+ rest.push(post);
+ }
+ }
+
+ queue = openPosts.concat(fpPosts.concat(rest));
+ loadPost();
+ };
+
+ postLoaded = function (data) {
+ if (queue.length == 0) {
+ return;
+ }
+
+ if (data.indexOf('-#') == 0) {
+ data = data.split('#');
+ if (queue[0].id != data[1]) {
+ loadPost();
+ return;
+ }
+ queue[0].loading = false;
+ queue[0].contents = '
' + TopicView.loadError + '
';
+ } else {
+ data = data.split('\n');
+ var l = data.shift().split('#');
+ if (queue[0].id != l[1]) {
+ loadPost();
+ return;
+ }
+ queue[0].loading = false;
+ queue[0].contents = data.join('\n');
+ }
+ queue[0].loaded = true;
+
+ var el = document.getElementById("tp-post-" + queue[0].id);
+ if (el) {
+ el.innerHTML = displayPost(queue[0]);
+ }
+
+ queue.shift();
+ loadPost();
+ };
+
+ loadPost = function () {
+ if (queue.length == 0 || queue[0].loading) {
+ return;
+ }
+
+ queue[0].loading = true;
+ x_loadPostContents(topicId, pageMD5, queue[0].id, function (data) {
+ postLoaded(data);
+ });
+ };
+
+ this.parse = function (data) {
+ if (data.indexOf('\n') == -1) {
+ // IE, first update
+ data = data.split('#');
+ topicId = data.shift();
+ pageMD5 = data.shift();
+ this.update();
+ return;
+ }
+
+ data = data.split('\n');
+ var l = data.shift().split('#');
+ topicId = l.shift();
+ pageMD5 = l.shift();
+ if (parseInitialContents(data)) {
+ pageUpdater = window.setTimeout("pageContents.update()", 10000);
+ }
+ locked = false;
+ };
+
+ this.update = function () {
+ if (locked) {
+ return;
+ }
+ pageUpdater = null;
+ locked = true;
+ x_getTopic(topicId, pageMD5, function (data) { pageContents.parse(data); });
+ };
+
+ this.togglePost = function (postId) {
+ var post = posts[postId];
+ post.open = ! post.open;
+ var el = document.getElementById("tp-post-" + post.id);
+ if (el) {
+ el.innerHTML = displayPost(post);
+ }
+ };
+
+ this.setFieldValues = function () { };
+};
+
+
+ForumView = function () {
+ var me = this;
+
+ var pageUpdater = null;
+ var locked = false;
+ var pageMD5 = null;
+ var viewId = null;
+ var players = [];
+
+ var nPages = 0;
+ var cPage = -1;
+ var perPage = 10;
+
+ var topics = [];
+ var isMod = false;
+ var canPost = false;
+ var vDeleted = false;
+ var unread = false;
+ var admins = null;
+ var mods = null;
+ var users = null;
+ var hasMoveTargets = false;
+ var moveTargets = {};
+ var description = '';
+ var title = '';
+ var parents = null;
+
+ var showDetails = false;
+ var showModTools = false;
+ var modSelAll = false;
+ var showOptions = false;
+ var options = { };
+ var modTools = { };
+ var selTopicsStr = '';
+
+ var mainParser, parseTopic, displayContents, drawControls, drawModTools, setFieldValues, getSelectedTopics;
+
+ mainParser = function (lines) {
+ var line = lines.shift().split('#');
+ var nt, ndl, npe, na, nm, nu, nmt;
+
+ forumId = line.shift();
+ nt = parseInt(line.shift(), 10);
+ unread = (line.shift() == '1');
+ isMod = (line.shift() == '1');
+ canPost = (line.shift() == '1');
+ perPage = parseInt(line.shift(), 10);
+ vDeleted = (line.shift() == '1');
+ ndl = parseInt(line.shift(), 10);
+ npe = parseInt(line.shift(), 10);
+ na = parseInt(line.shift(), 10);
+ nm = parseInt(line.shift(), 10);
+ nu = parseInt(line.shift(), 10);
+ nmt = isMod ? parseInt(line.shift(), 10) : 0;
+ hasMoveTargets = (nmt > 0);
+ title = lines.shift();
+
+ var dc = new Array();
+ for (var i = 0; i < ndl; i ++) {
+ dc.push(lines.shift());
+ }
+ description = dc.join('
');
+
+ parents = new Array();
+ for (var i = 0; i < npe; i ++) {
+ line = lines.shift().split('#');
+ parents.push({
+ id: line.shift(),
+ name: line.join('#')
+ });
+ }
+
+ admins = new Array();
+ for (var i = 0; i < na; i ++) {
+ admins.push(lines.shift());
+ }
+ mods = new Array();
+ for (var i = 0; i < nm; i ++) {
+ mods.push(lines.shift());
+ }
+ users = new Array();
+ for (var i = 0; i < nu; i ++) {
+ users.push(lines.shift());
+ }
+
+ moveTargets = {};
+ for (var i = 0; i < nmt; i ++) {
+ line = lines.shift().split('#');
+ var ln = line.shift();
+ moveTargets[ln] = line.join('#');
+ }
+
+ selTopicsStr = '';
+ for (var i in topics) {
+ if (topics[i].selected) {
+ selTopicsStr += '#' + topics[i].id + '#';
+ }
+ }
+
+ topics = new Array();
+ for (var i = 0; i < nt; i ++) {
+ topics.push(parseTopic(lines));
+ }
+
+ if (nt == 0) {
+ cPage = -1;
+ } else {
+ nPages = Math.ceil(nt / perPage);
+ if (cPage < 0) {
+ cPage = 0;
+ } else if (cPage >= nPages) {
+ cPage = nPages - 1;
+ }
+ }
+ };
+
+ parseTopic = function (lines) {
+ var topic = { };
+ var line = lines.shift().split('#');
+
+ topic.id = line.shift();
+ topic.movedTo = line.shift();
+ topic.unread = (line.shift() == '1');
+ topic.sticky = parseInt(line.shift(), 10);
+ topic.nReplies = line.shift();
+ topic.fpTime = line.shift();
+ topic.fpAuthor = line.shift();
+ topic.lcTime = line.shift();
+ topic.lcAuthor = line.shift();
+ topic.isLocked = (line.shift() == '1');
+ topic.hasPoll = (line.shift() == '1');
+ topic.isDeleted = (line.shift() == '1');
+ topic.deletedAt = line.shift();
+ topic.deletedBy = line.shift();
+ topic.title = lines.shift();
+ topic.mToForum = (topic.movedTo == '') ? null : lines.shift();
+ topic.selected = (selTopicsStr.indexOf( '#' + topic.id + '#') != -1);
+
+ return topic;
+ };
+
+ getSelectedTopics = function (deleted) {
+ var rv = new Array();
+ for (var i = cPage * perPage; i < topics.length && i < (cPage + 1) * perPage; i ++) {
+ if (topics[i].movedTo == '' && topics[i].selected && topics[i].isDeleted == deleted) {
+ rv.push(topics[i].id);
+ }
+ }
+ return rv;
+ };
+
+ drawControls = function () {
+ // Main controls
+ var str = '
'
+ + ''
+ + ''
+ + ''
+ + '' + ForumView.displayOptions + ' ';
+
+ // Moderation tools
+ if (isMod) {
+ str += ''
+ + '' + ForumView.modTools + ' '
+ + ' ';
+ }
+ str += ' ';
+
+ // Page control
+ if (topics.length && nPages > 1) {
+ var st = 'border-width: 0px; margin: 0px; vertical-align: middle; ';
+ str += ''
+ + (cPage > 0 ? '' : '')
+ + '<-- ' + ForumView.previousPage + (cPage > 0 ? ' ' : '')
+ + ' '
+ + ' '
+ + ((cPage' : '')
+ + ForumView.nextPage + '-->' + ((cPage' : '') + ' ';
+ }
+
+ str += '
';
+ return str;
+ };
+
+ displayContents = function () {
+ // Draw the header
+ var str = '';
+ // Details (description & ACL)
+ if (hasDetails) {
+ var needsBR = false;
+ str += '' + ForumView.details + ' ';
+
+ if (description != '') {
+ str += description;
+ needsBR = true;
+ }
+
+ if (admins.length) {
+ str += (needsBR ? ' ' : '') + '' + ForumView.adminsHdr + ' : '
+ + admins.join(' - ');
+ needsBR = true;
+ }
+
+ if (mods.length) {
+ str += (needsBR ? ' ' : '') + '' + ForumView.modsHdr + ' : '
+ + mods.join(' - ');
+ needsBR = true;
+ }
+
+ if (users.length) {
+ str += (needsBR ? ' ' : '') + '' + ForumView.usersHdr + ' : '
+ + users.join(' - ');
+ }
+
+ str += ' ';
+ }
+ str += '';
+
+ str += drawControls();
+ if (topics.length) {
+ // Topics list
+ str += '
';
+
+ document.getElementById('f-page').innerHTML = str;
+ setFieldValues();
+ };
+
+ hideOptions = function () {
+ var e = document.getElementById('f-options');
+ if (!e) {
+ return;
+ }
+ showOptions = false;
+ e.style.display = 'none';
+ document.getElementById('f-std-ctrl').style.display = 'block';
+ };
+
+ drawModTools = function () {
+ var cnt = 0, sel = 0, dSel = 0, nSel = 0, hasLocked = false, hasUnlocked = false,
+ minStL = 11, maxStL = -1;
+ if (cPage != -1) {
+ for (var i = cPage * perPage; i < topics.length && i < (cPage + 1) * perPage; i ++) {
+ if (topics[i].movedTo != '') {
+ continue;
+ }
+ document.getElementById('mt-sel-' + topics[i].id).checked = topics[i].selected;
+ if (topics[i].selected) {
+ if (topics[i].isDeleted) {
+ dSel ++;
+ } else {
+ nSel ++;
+ hasLocked = hasLocked || topics[i].isLocked;
+ hasUnlocked = hasUnlocked || ! topics[i].isLocked;
+ }
+ minStL = (minStL > topics[i].sticky) ? topics[i].sticky : minStL;
+ maxStL = (maxStL < topics[i].sticky) ? topics[i].sticky : maxStL;
+ sel ++;
+ }
+ cnt ++;
+ }
+ document.getElementById('mt-sel-all').checked = modSelAll = (sel == cnt);
+ }
+
+ var str = '' + ForumView.hideModTools
+ + ' ';
+ if (!(dSel || nSel)) {
+ str += ' ' + ForumView.pleaseSelect;
+ } else {
+ if (nSel) {
+ str += ' ' + ForumView.selectedTopics
+ + ''
+ + ForumView.deleteTopics + ' - ' + ForumView.stickyLevel;
+
+ // Sticky level management
+ if (maxStL < 10) {
+ str += ''
+ + ForumView.increaseStickyLevel + ' / ';
+ }
+ if (minStL > 0) {
+ str += ''
+ + ForumView.decreaseStickyLevel + ' / ';
+ }
+
+ str += ForumView.setTo + '------- '
+
+ var stText = [ForumView.normalPost, 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII',
+ 'IX', 'X'];
+ for (var i = 0; i < 11; i ++) {
+ str += '' + stText[i] + ' ';
+ }
+ str += ' ';
+
+ // Lock / Unlock
+ if (hasLocked) {
+ str += ' - '
+ + ForumView.unlock + ' ';
+ }
+ if (hasUnlocked) {
+ str += ' - '
+ + ForumView.lock + ' ';
+ }
+
+ // Move to
+ if (hasMoveTargets) {
+ str += ' ' + ForumView.moveTo + ''
+ + '------- ';
+ for (var i in moveTargets) {
+ str += '' + moveTargets[i] + ' ';
+ }
+ str += ' ';
+ }
+ }
+ if (dSel) {
+ str += ' ' + ForumView.deletedTopics
+ + ''
+ + ForumView.restoreTopics + ' ';
+ }
+ }
+
+ document.getElementById('f-mod-tools-contents').innerHTML = str;
+ };
+
+ setFieldValues = function () {
+ var e = document.getElementById('f-options');
+ if (!e) {
+ return;
+ }
+
+ // Options block
+ document.getElementById('f-apply-to-this').checked = (options.toAll == 0);
+ document.getElementById('f-apply-to-all').checked = (options.toAll == 1);
+ document.getElementById('f-per-page').selectedIndex = (options.pp / 10) - 1;
+
+ // Moderation tools
+ if (! isMod) {
+ return;
+ }
+ document.getElementById('f-disp-del').checked = (options.dd == 1);
+
+ if (cPage != -1) {
+ for (var i = cPage * perPage; i < topics.length && i < (cPage + 1) * perPage; i ++) {
+ document.getElementById('mt-sel-' + topics[i].id).style.display =
+ ((showModTools && topics[i].movedTo == '') ? 'block' : 'none');
+ }
+ document.getElementById('mt-sel-all').style.display = (showModTools ? 'block' : 'none');
+ }
+
+ drawModTools();
+ };
+
+ // Page update: parser & updater
+ this.parse = function (data) {
+ if (data != '-') {
+ if (data.indexOf('\n') == -1) {
+ // IE, first update
+ viewId = data;
+ this.update();
+ return;
+ }
+
+ var lines = data.split('\n');
+ pageMD5 = lines.shift();
+ viewId = lines.shift();
+
+ mainParser(lines);
+ players = parseNames(lines);
+
+ displayContents();
+ }
+
+ pageUpdater = window.setTimeout("pageContents.update()", 10000);
+ locked = false;
+ };
+ this.update = function () {
+ if (locked) {
+ return;
+ }
+ pageUpdater = null;
+ locked = true;
+ x_getView(viewId, pageMD5, function (data) { pageContents.parse(data); });
+ };
+ this.setFieldValues = function () { setFieldValues(); };
+
+ // Displaying details
+ this.toggleDetails = function () {
+ var e = document.getElementById('f-details');
+ if (!e) {
+ return;
+ }
+ showDetails = ! showDetails;
+ document.getElementById('f-toggle-details').innerHTML
+ = (showDetails ? ForumView.hideDetails : ForumView.showDetails)
+ e.style.display = showDetails ? 'block' : 'none';
+ };
+
+ // "Display options" box management
+ this.displayOptions = function () {
+ var e = document.getElementById('f-options');
+ if (!e) {
+ return;
+ }
+ options = {
+ toAll: 0,
+ pp: perPage,
+ dd: (isMod && vDeleted) ? 1 : 0
+ };
+ setFieldValues();
+ showOptions = true;
+ e.style.display = 'block';
+ document.getElementById('f-std-ctrl').style.display = 'none';
+ };
+ this.optionsOk = function () {
+ hideOptions();
+ if (locked) {
+ window.setTimeout("pageContents.optionsOk()", 250);
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+ x_forumOptions(forumId, options.toAll, options.pp, options.dd, pageMD5, function (data) {
+ pageContents.parse(data); });
+ };
+ this.optionsCancel = function () { hideOptions(); };
+ this.setOption = function (name, value) { options[name] = value; };
+
+ // Moderation tools
+ this.displayModTools = function () {
+ var e = document.getElementById('f-mod-tools');
+ if (!e) {
+ return;
+ }
+ showModTools = true;
+ setFieldValues();
+ e.style.display = 'block';
+ document.getElementById('f-std-ctrl').style.display = 'none';
+ };
+ this.hideModTools = function () {
+ var e = document.getElementById('f-mod-tools');
+ if (!e) {
+ return;
+ }
+ showModTools = false;
+ setFieldValues();
+ e.style.display = 'none';
+ document.getElementById('f-std-ctrl').style.display = 'block';
+ };
+ this.toggleTopic = function (index) {
+ topics[index].selected = !topics[index].selected;
+ drawModTools();
+ };
+ this.toggleSelAll = function () {
+ modSelAll = !modSelAll;
+ for (var i = cPage * perPage; i < topics.length && i < (cPage + 1) * perPage; i ++) {
+ if (topics[i].movedTo != '') {
+ continue;
+ }
+ topics[i].selected = modSelAll;
+ }
+ drawModTools();
+ };
+ this.restoreSelected = function () {
+ if (locked) {
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(true);
+ x_restoreTopics(forumId, tlist.join('#'), function (data) { pageContents.parse(data); });
+ };
+ this.deleteSelected = function () {
+ if (locked) {
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_deleteTopics(forumId, tlist.join('#'), function (data) { pageContents.parse(data); });
+ };
+ this.increaseSticky = function () {
+ if (locked) {
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_changeTopicsLevel(forumId, tlist.join('#'), 1, function (data) { pageContents.parse(data); });
+ };
+ this.decreaseSticky = function () {
+ if (locked) {
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_changeTopicsLevel(forumId, tlist.join('#'), -1, function (data) { pageContents.parse(data); });
+ };
+ this.setSticky = function (value) {
+ var e = document.getElementById('mt-set-level');
+ if (e) { e.disabled = true; }
+ e = document.getElementById('mt-set-level'); if (e) { e.disabled = true; }
+ e = document.getElementById('mt-move-to'); if (e) { e.disabled = true; }
+
+ if (locked) {
+ window.setTimeout("pageContents.setSticky(" + value + ")", 250);
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_setTopicsLevel(forumId, tlist.join('#'), value, function (data) { pageContents.parse(data); });
+ };
+ this.lockTopics = function () {
+ if (locked) {
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_setTopicsLock(forumId, tlist.join('#'), 1, function (data) { pageContents.parse(data); });
+ };
+ this.unlockTopics = function () {
+ if (locked) {
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_setTopicsLock(forumId, tlist.join('#'), 0, function (data) { pageContents.parse(data); });
+ };
+ this.moveTo = function (dest) {
+ e = document.getElementById('mt-set-level'); if (e) { e.disabled = true; }
+ e = document.getElementById('mt-move-to'); if (e) { e.disabled = true; }
+
+ if (locked) {
+ window.setTimeout("pageContents.moveTo(" + dest + ")", 250);
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+
+ var tlist = getSelectedTopics(false);
+ x_moveTopics(forumId, tlist.join('#'), dest, function (data) { pageContents.parse(data); });
+ };
+
+ // Page management
+ this.nextPage = function () { this.jumpToPage(cPage + 1); };
+ this.prevPage = function () { this.jumpToPage(cPage - 1); };
+ this.jumpToPage = function (value) {
+ cPage = parseInt(value, 10);
+ displayContents();
+ };
+
+ // Mark topics as read
+ this.markRead = function () {
+ if (locked) {
+ window.setTimeout("pageContents.markRead()", 250);
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+ x_forumRead(forumId, function (data) { pageContents.parse(data); });
+ };
+};
+
+
+CategoryView = function () {
+
+ var me = this;
+ var tst = ' style="width: 100%; margin: 0px; padding: 0px; border-width: 0px"';
+ var cst = ' style="margin: 0px; padding: 0px; border-width: 0px; vertical-align: middle"';
+
+ var pageUpdater = null;
+ var pageMD5 = null;
+ var viewId = null;
+ var contents = null;
+ var locked = false;
+ var players = [];
+
+ var parseContents, parseForum, displayContents, displayForums;
+
+ parseContents = function (lines) {
+ var line = lines.shift().split('#');
+ var obj = {};
+ var cc, dc;
+
+ obj.id = line.shift();
+ obj.isCategory = (line.shift() == 'F');
+ obj.hasUnread = (line.shift() == '1');
+ cc = parseInt(line.shift(), 10);
+ dc = parseInt(line.shift(), 10);
+
+ if (obj.isCategory) {
+ obj.typeName = lines.shift();
+ }
+ obj.title = lines.shift();
+
+ var da = new Array();
+ for (var i = 0; i < dc; i ++) {
+ da.push(lines.shift());
+ }
+ obj.description = da.join(' ');
+
+ if (obj.id == '/') {
+ obj.title = CategoryView.ovTitle;
+ obj.description = CategoryView.ovDescription;
+ }
+
+ obj.contents = new Array();
+ for (var i = 0; i < cc; i ++) {
+ obj.contents.push( obj.isCategory ? parseForum(lines) : parseContents(lines) );
+ }
+
+ return obj;
+ };
+ parseForum = function (lines) {
+ var line = lines.shift().split('#');
+ var obj = { };
+ var dc;
+
+ obj.id = line.shift();
+ dc = parseInt(line.shift(), 10);
+ obj.isDeleted = (line.shift() == '1');
+ obj.deletedAt = line.shift();
+ obj.deletedBy = line.shift();
+ obj.topics = line.shift();
+ obj.posts = line.shift();
+ obj.isUnread = (line.shift() == '1');
+
+ if (parseInt(obj.posts, 10) > 0) {
+ line = lines.shift().split('#');
+ obj.lastAuthor = line.shift();
+ obj.lastTimestamp = line.shift();
+ }
+
+ obj.title = lines.shift();
+ var desc = new Array();
+ for (var i = 0; i < dc; i ++) {
+ desc.push(lines.shift());
+ }
+ obj.description = desc.join(' ');
+
+ return obj;
+ };
+ displayContents = function (obj, depth) {
+ var d = (typeof depth == 'undefined') ? 0 : depth;
+ var mw = d * 8;
+ var htag = 'h' + (d + 1);
+
+ var str = '';
+ if (d > 0) {
+ str += ''
+ + ' ';
+ }
+
+ var rText = '';
+ if (obj.isCategory) {
+ rText = '';
+ }
+
+ str += '' + rText + '<' + htag + '>' + obj.title + '' + htag + '>'
+ + (obj.description != '' ? ('
' + obj.description + '
') : '')
+ + '
';
+
+ if (! obj.isCategory) {
+ for (var i in obj.contents) {
+ str += displayContents(obj.contents[i], d + 1);
+ }
+ } else {
+ str += displayForums(obj);
+ }
+
+ return str;
+ };
+ displayForums = function (obj) {
+ if (obj.contents.length == 0) {
+ return '' + CategoryView.empty + '
';
+ }
+
+ var str = ''
+ + ' '
+ + CategoryView.headers.name + ' ' + CategoryView.headers.topics
+ + ' ' + CategoryView.headers.posts
+ + ' ' + CategoryView.headers.lastPost
+ + ' ';
+
+ for (var i in obj.contents) {
+ var forum = obj.contents[i];
+ str += ' '
+ + '' + forum.title + ' '
+ + (forum.description != '' ? (' ' + forum.description) : '') + ' ';
+ if (forum.isDeleted) {
+ str += ''
+ + CategoryView.deletedAt + '' + formatDate(forum.deletedAt) + ' '
+ + CategoryView.by + '' + players[forum.deletedBy] + ' ';
+ } else {
+ str += ''
+ + formatNumber(forum.topics)
+ + ' '
+ + formatNumber(forum.posts)
+ + ' ';
+ if (forum.posts != 0) {
+ str += formatDate(forum.lastTimestamp) + ' ' + CategoryView.by
+ + '' + players[forum.lastAuthor] + ' ';
+ } else {
+ str += CategoryView.noPosts;
+ }
+ str += ' ';
+ }
+ str += ' ';
+ }
+
+ str += '
';
+ return str;
+ };
+
+ this.parse = function (data) {
+ if (data != '-') {
+ if (data.indexOf('\n') == -1) {
+ // IE, first update
+ viewId = data;
+ this.update();
+ return;
+ }
+
+ var lines = data.split('\n');
+ pageMD5 = lines.shift();
+ viewId = lines.shift();
+
+ contents = parseContents(lines);
+ players = parseNames(lines);
+
+ document.getElementById('f-page').innerHTML = displayContents(contents);
+ }
+
+ pageUpdater = window.setTimeout("pageContents.update()", 10000);
+ locked = false;
+ };
+
+ this.update = function () {
+ if (locked) {
+ return;
+ }
+ pageUpdater = null;
+ locked = true;
+ x_getView(viewId, pageMD5, function (data) { pageContents.parse(data); });
+ };
+
+ this.markRead = function (id) {
+ if (locked) {
+ window.setTimeout("pageContents.markRead('" + id + "')", 250);
+ return;
+ }
+ locked = true;
+ if (pageUpdater) {
+ window.clearTimeout(pageUpdater);
+ pageUpdater = null;
+ }
+ x_categoryRead(id, viewId, function (data) { pageContents.parse(data); });
+ };
+
+ this.setFieldValues = function () { };
+};
+
+
+
+ForumsLayout = function () {
+
+ var init = document.getElementById('f-params').innerHTML.split('#');
+ var me = this;
+
+ // Read the page's parameters
+ var menuVisible = (init.shift() == '1');
+ var needData = (init.shift() == '1');
+ var pageType = init.shift();
+
+ // Read the current menu entry
+ MenuItem.current = document.getElementById('f-menu-current').innerHTML;
+
+ // Initialize other private variables here
+ var menuMD5 = '';
+ var menuTree = null;
+ var menuUpdater = null;
+ var menuFDisabled = false;
+ var page = null;
+
+ // Initialize private methods here
+ var parseMenuData, drawLayout, drawMenu;
+ parseMenuData = function(data) {
+ menuUpdater = null;
+ if (! menuVisible) {
+ menuFDisabled = false;
+ return;
+ }
+
+ var lines = data.split('\n');
+ var line = lines.shift();
+
+ if (line != '-') {
+ menuMD5 = line;
+ menuTree = new MenuItem(lines);
+ drawMenu();
+ }
+ menuFDisabled = false;
+ menuUpdater = window.setTimeout("main.updateMenu()", 5000);
+ };
+ drawMenu = function () {
+ if (! menuTree) {
+ menuVisible = false;
+ drawLayout();
+ return;
+ }
+
+ var tst = ' style="width: 100%; margin: 0px; padding: 0px; border-width: 0px"';
+ var cst = ' style="margin: 0px; padding: 0px; border-width: 0px; vertical-align: middle"';
+ var str = ' ' + ' ';
+
+ var x = new Array();
+ menuTree.draw(x);
+
+ str += x.join('') + '
';
+ document.getElementById('f-menu').innerHTML = str;
+ };
+ drawLayout = function () {
+ var mContents;
+ if (document.getElementById('f-page')) {
+ mContents = document.getElementById('f-page').innerHTML;
+ } else {
+ mContents = ' ';
+ }
+
+ var mainMargin;
+ var str = '
';
+ document.getElementById('f-contents').innerHTML = str;
+ document.getElementById('f-page').innerHTML = mContents;
+ if (mContents != ' ') {
+ pageContents.setFieldValues();
+ }
+ };
+
+ // Public methods
+ this.updateMenu = function() {
+ menuFDisabled = true;
+ x_getMenu(menuMD5, parseMenuData);
+ };
+ this.hideMenu = function() {
+ if (menuFDisabled || !menuVisible) {
+ if (menuFDisabled) {
+ window.setTimeout("main.hideMenu()", 250);
+ }
+ return;
+ }
+ if (menuUpdater) {
+ window.clearTimeout(menuUpdater);
+ }
+ menuUpdater = menuMD5 = menuTree = null;
+ menuVisible = false;
+ x_hideMenu(function () {});
+ drawLayout();
+ };
+ this.showMenu = function() {
+ if (menuFDisabled || menuVisible) {
+ if (menuFDisabled) {
+ window.setTimeout("main.showMenu()", 250);
+ }
+ return;
+ }
+ menuFDisabled = true;
+ menuVisible = true;
+ drawLayout();
+ x_showMenu(parseMenuData);
+ };
+ this.menuOpen = function(id) {
+ if (menuFDisabled || !menuVisible) {
+ if (menuFDisabled) {
+ window.setTimeout("main.menuOpen('" + id + "')", 250);
+ }
+ return;
+ }
+ menuFDisabled = true;
+ if (menuUpdater) {
+ window.clearTimeout(menuUpdater);
+ menuUpdater = null;
+ }
+ x_menuOpen(id, parseMenuData);
+ };
+ this.menuClose = function(id) {
+ if (menuFDisabled || !menuVisible) {
+ if (menuFDisabled) {
+ window.setTimeout("main.menuClose('" + id + "')", 250);
+ }
+ return;
+ }
+ menuFDisabled = true;
+ if (menuUpdater) {
+ window.clearTimeout(menuUpdater);
+ menuUpdater = null;
+ }
+ x_menuClose(id, parseMenuData);
+ };
+
+ useGIFs = needData;
+ pageContents = new ForumsLayout.pages[pageType];
+ drawLayout();
+ if (needData) {
+ if (menuVisible) {
+ x_getMenu(parseMenuData);
+ }
+ } else {
+ if (menuVisible) {
+ parseMenuData(document.getElementById('f-menu-init').innerHTML);
+ }
+ }
+ pageContents.parse(document.getElementById('f-page-init').innerHTML);
+};
+
+ForumsLayout.pages = {
+ vCat: CategoryView,
+ vForum: ForumView,
+ vTopic: TopicView
+};
diff -Naur beta5//site/static/beta5/js/pg_overview-en.js forums//site/static/beta5/js/pg_overview-en.js
--- beta5//site/static/beta5/js/pg_overview-en.js 2011-02-05 10:09:56.434335002 +0100
+++ forums//site/static/beta5/js/pg_overview-en.js 2011-03-12 15:10:45.561300049 +0100
@@ -84,26 +84,7 @@
str += 'Fleets Total fleet power: '+formatNumber(flOverview[0])+'
';
str += 'Money Daily Profit: €'+formatNumber(moOverview[2])+'
';
- str += 'Forums ';
- var i,j,k,a=new Array();
- for (i=0;i1 ? 's' : '')));
- a.push(''+name+' : ' + j);
- }}
-
- if (aForums.length)
- {
- k = 0;
- for (j=0;j1 ? 's' : '')));
- a.push('Alliance forums : ' + j);
- }
- str += a.join(' ') + '
';
+ str += 'Forums ' + forums.output(-1, false) + '
';
str += 'Planets '+formatNumber(unOverview[0])+' planets
';
str += 'Next ticks
';
@@ -188,30 +169,7 @@
str += 'Daily Profit: €'+formatNumber(moOverview[2])+' ';
str += 'More details... ';
- str += 'Forums ';
- var j,a=new Array(),s;
- for (i=0;i (view )';
- for (j=0;j - ' + forums[j].name + ' : ';
- s += makeTopicsText(forums[j].nTopics, forums[j].nUnread);
- }
- a.push(s);
- }}
-
- if (aForums.length)
- {
- s = 'Alliance Forums (view )';
- for (j=0;j - ' + aForums[j].name + ' : ';
- s += makeTopicsText(aForums[j].nTopics, aForums[j].nUnread);
- }
- a.push(s);
- }
- str += a.join(' ') + '
';
+ str += 'Forums ' + forums.output(-1, true) + '
';
str += 'Universe '+formatNumber(unOverview[0])+' planets';// (';
str += /*formatNumber(unOverview[2]) + ' at the same prot. level)*/'';
@@ -240,6 +198,40 @@
}
+function __forumsOutput(depth, complete) {
+ var str = '';
+
+ if (this.id != '/') {
+ for (var i = 0; i < depth; i++) {
+ str += ' ';
+ }
+ str += '' + this.name + ' : ';
+ if (complete) {
+ str += '' + this.topics + ' topic' + (this.unread > 1 ? 's' : '');
+ if (this.unread > 0) {
+ str += ' (' + this.unread + ' unread)';
+ }
+ } else {
+ if (this.unread == 0) {
+ str += 'no unread topics';
+ } else {
+ str += '' + this.unread + ' unread topic' + (this.unread > 1 ? 's' : '');
+ }
+ }
+ }
+
+ for (var i = 0; i < this.contents.length; i ++) {
+ if (this.contents[i].type == 'F' && ! complete) {
+ continue;
+ }
+
+ str += ' ' + this.contents[i].output(depth + 1, complete);
+ }
+
+ return str;
+}
+
+
function confirmBreakProtection() {
return confirm('You are about to break away from Peacekeeper protection.\n'
+ 'Anyone will be able to attack your planets afterwards.\n'
diff -Naur beta5//site/static/beta5/js/pg_overview.js forums//site/static/beta5/js/pg_overview.js
--- beta5//site/static/beta5/js/pg_overview.js 2011-02-05 10:09:56.434335002 +0100
+++ forums//site/static/beta5/js/pg_overview.js 2011-03-12 15:08:00.801300049 +0100
@@ -1,5 +1,5 @@
var dFolders, cFolders;
-var genForums, aForums, allianceId;
+var forums;
var plOverview, flOverview, moOverview, nResearch;
var unOverview,stDiff,ticks,tUpdate,rankings;
var complete, protection, updateTimer;
@@ -110,24 +110,25 @@
this.name = name;
}
-function Category(id, type, name)
-{
- this.id = id;
- this.type = type;
- this.name = name;
- this.forums = new Array();
-}
+function ForumsEntity(inputData) {
+ var iLine = inputData.shift().split('#');
+ var nElements;
+
+ this.type = iLine.shift();
+ this.id = iLine.shift();
+ nElements = parseInt(iLine.shift(), 10);
+ this.topics = parseInt(iLine.shift(), 10);
+ this.unread = parseInt(iLine.shift(), 10);
+ this.name = inputData.shift();
+ this.contents = new Array();
+ this.output = __forumsOutput;
-function Forum(id, nTopics, nUnread, name)
-{
- this.id = id;
- this.nTopics = nTopics;
- this.nUnread = nUnread;
- this.name = name;
+ for (var i = 0; i < nElements; i ++) {
+ this.contents.push( new ForumsEntity(inputData) );
+ }
}
-
function initPage() {
overviewReceived(document.getElementById('init-data').value);
}
@@ -140,55 +141,26 @@
}
-function parseComms(l)
-{
- var i, a = l.shift().split('#');
- var nCustom = parseInt(a[0],10), nGenCats = parseInt(a[1],10), nAForums = parseInt(a[2],10);
- allianceId = a[3];
+function parseComms(l) {
+ var i, a, nCustom;
// Default folders
dFolders = new Array();
- for (i=0;i<3;i++)
- {
+ for (i=0;i<3;i++) {
a = l.shift().split('#');
dFolders.push(new Folder('', a[0], a[1], ''));
}
// Custom folders
+ nCustom = parseInt(l.shift(), 10);
cFolders = new Array();
- for (i=0;i