function get_subscribed_topic_func()
{
    global $config, $db, $user, $auth, $mobiquo_config;
    // Only registered users can go beyond this point
    if (!$user->data['is_registered']) {
        return get_error(9);
    }
    $topic_list = array();
    if ($config['allow_topic_notify']) {
        $forbidden_forums = $auth->acl_getf('!f_read', true);
        $forbidden_forums = array_unique(array_keys($forbidden_forums));
        if (isset($mobiquo_config['hide_forum_id'])) {
            $forbidden_forums = array_unique(array_merge($forbidden_forums, $mobiquo_config['hide_forum_id']));
        }
        $sql_array = array('SELECT' => 't.*, 
                            f.forum_name,
                            u.user_avatar,
                            u.user_avatar_type', 'FROM' => array(TOPICS_WATCH_TABLE => 'tw', TOPICS_TABLE => 't', USERS_TABLE => 'u'), 'WHERE' => 'tw.user_id = ' . $user->data['user_id'] . '
                AND t.topic_id = tw.topic_id
                AND u.user_id = t.topic_last_poster_id
                AND ' . $db->sql_in_set('t.forum_id', $forbidden_forum_ary, true, true), 'ORDER_BY' => 't.topic_last_post_time DESC');
        $sql_array['LEFT_JOIN'] = array();
        $sql_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TABLE => 'f'), 'ON' => 't.forum_id = f.forum_id');
        if ($config['allow_bookmarks']) {
            $sql_array['SELECT'] .= ', bm.topic_id as bookmarked';
            $sql_array['LEFT_JOIN'][] = array('FROM' => array(BOOKMARKS_TABLE => 'bm'), 'ON' => 'bm.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = bm.topic_id');
        }
        $sql = $db->sql_build_query('SELECT', $sql_array);
        $result = $db->sql_query_limit($sql, 20);
        $topic_list = array();
        while ($row = $db->sql_fetchrow($result)) {
            $forum_id = $row['forum_id'];
            $topic_id = isset($row['b_topic_id']) ? $row['b_topic_id'] : $row['topic_id'];
            // Replies
            $replies = $auth->acl_get('m_approve', $forum_id) ? $row['topic_replies_real'] : $row['topic_replies'];
            if ($row['topic_status'] == ITEM_MOVED && !empty($row['topic_moved_id'])) {
                $topic_id = $row['topic_moved_id'];
            }
            // Get folder img, topic status/type related information
            $folder_img = $folder_alt = $topic_type = '';
            topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
            $short_content = get_short_content($row['topic_last_post_id']);
            if ($forum_id) {
                $topic_tracking = get_complete_topic_tracking($forum_id, $topic_id);
                $new_post = $topic_tracking[$topic_id] < $row['topic_last_post_time'] ? true : false;
            } else {
                $new_post = false;
            }
            $user_avatar_url = get_user_avatar_url($row['user_avatar'], $row['user_avatar_type']);
            $allow_change_type = $auth->acl_get('m_', $forum_id) || $user->data['is_registered'] && $user->data['user_id'] == $row['topic_poster'] ? true : false;
            $xmlrpc_topic = new xmlrpcval(array('forum_id' => new xmlrpcval($forum_id), 'forum_name' => new xmlrpcval(html_entity_decode($row['forum_name']), 'base64'), 'topic_id' => new xmlrpcval($topic_id), 'topic_title' => new xmlrpcval(html_entity_decode(strip_tags(censor_text($row['topic_title']))), 'base64'), 'reply_number' => new xmlrpcval(intval($replies), 'int'), 'view_number' => new xmlrpcval(intval($row['topic_views']), 'int'), 'short_content' => new xmlrpcval($short_content, 'base64'), 'post_author_id' => new xmlrpcval($row['topic_last_poster_id']), 'post_author_name' => new xmlrpcval(html_entity_decode($row['topic_last_poster_name']), 'base64'), 'new_post' => new xmlrpcval($new_post, 'boolean'), 'post_time' => new xmlrpcval(mobiquo_iso8601_encode($row['topic_last_post_time']), 'dateTime.iso8601'), 'icon_url' => new xmlrpcval($user_avatar_url), 'can_delete' => new xmlrpcval($auth->acl_get('m_delete', $forum_id), 'boolean'), 'can_bookmark' => new xmlrpcval($user->data['is_registered'] && $config['allow_bookmarks'], 'boolean'), 'isbookmarked' => new xmlrpcval($row['bookmarked'] ? true : false, 'boolean'), 'can_close' => new xmlrpcval($auth->acl_get('m_lock', $forum_id) || $auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $row['topic_poster'], 'boolean'), 'is_closed' => new xmlrpcval($row['topic_status'] == ITEM_LOCKED, 'boolean'), 'can_stick' => new xmlrpcval($allow_change_type && $auth->acl_get('f_sticky', $forum_id) && $row['topic_type'] != POST_STICKY, 'boolean')), 'struct');
            $topic_list[] = $xmlrpc_topic;
        }
        $db->sql_freeresult($result);
    }
    $topic_num = count($topic_list);
    $response = new xmlrpcval(array('total_topic_num' => new xmlrpcval($topic_num, 'int'), 'topics' => new xmlrpcval($topic_list, 'array')), 'struct');
    return new xmlrpcresp($response);
}
function get_topic_func($xmlrpc_params)
{
    global $db, $auth, $user, $config;
    $user->setup('viewforum');
    $params = php_xmlrpc_decode($xmlrpc_params);
    list($start, $limit) = process_page($params[1], $params[2]);
    // get forum id from parameters
    $forum_id = intval($params[0]);
    if (!$forum_id) {
        trigger_error('NO_FORUM');
    }
    // check if need sticky/announce topic only
    $topic_type = '';
    if (isset($params[3])) {
        // check if need sticky topic only
        if ($params[3] == 'TOP') {
            $topic_type = POST_STICKY;
            $start = 0;
            $limit = 20;
        } else {
            if ($params[3] == 'ANN') {
                $topic_type = POST_ANNOUNCE . ', ' . POST_GLOBAL;
                $start = 0;
                $limit = 20;
            }
        }
    }
    //    $default_sort_days  = (!empty($user->data['user_topic_show_days'])) ? $user->data['user_topic_show_days'] : 0;
    //    $default_sort_key   = (!empty($user->data['user_topic_sortby_type'])) ? $user->data['user_topic_sortby_type'] : 't';
    //    $default_sort_dir   = (!empty($user->data['user_topic_sortby_dir'])) ? $user->data['user_topic_sortby_dir'] : 'd';
    //
    //    $sort_days  = request_var('st', $default_sort_days); // default to get all topic
    //    $sort_key   = request_var('sk', $default_sort_key);  // default sort by last post time
    //    $sort_dir   = request_var('sd', $default_sort_dir);  // default sort as DESC
    $sort_days = 0;
    $sort_key = 't';
    $sort_dir = 'd';
    //------- Grab appropriate forum data --------
    $sql = "SELECT f.* FROM " . FORUMS_TABLE . " f WHERE f.forum_id = {$forum_id}";
    $result = $db->sql_query($sql);
    $forum_data = $db->sql_fetchrow($result);
    $db->sql_freeresult($result);
    // Forum does not exist
    if (!$forum_data) {
        trigger_error('NO_FORUM');
    }
    // Can not get topics from link forum
    if ($forum_data['forum_type'] == FORUM_LINK) {
        trigger_error('NO_FORUM');
    }
    // Permissions check
    if (!$auth->acl_gets('f_list', 'f_read', $forum_id) || $forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'] && !$auth->acl_get('f_read', $forum_id)) {
        if ($user->data['user_id'] != ANONYMOUS) {
            trigger_error('SORRY_AUTH_READ');
        }
        trigger_error('LOGIN_VIEWFORUM');
    }
    // Forum is passworded
    if ($forum_data['forum_password'] && !check_forum_password($forum_id)) {
        trigger_error('LOGIN_FORUM');
    }
    if (!$auth->acl_get('f_read', $forum_id)) {
        trigger_error('NO_READ_ACCESS');
    }
    // Topic ordering options
    $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => 't.topic_last_post_time', 'r' => 't.topic_replies', 's' => 't.topic_title', 'v' => 't.topic_views');
    // Limit topics to certain time frame, obtain correct topic count
    // global announcements must not be counted, normal announcements have to
    // be counted, as forum_topics(_real) includes them
    $sql_approved = $auth->acl_get('m_approve', $forum_id) ? '' : ' AND t.topic_approved = 1 ';
    // Get all shadow topics in this forum
    $sql = 'SELECT t.topic_moved_id, t.topic_id
            FROM ' . TOPICS_TABLE . ' t
            WHERE t.forum_id = ' . $forum_id . '
            AND t.topic_type IN (' . POST_NORMAL . ', ' . POST_STICKY . ', ' . POST_ANNOUNCE . ', ' . POST_GLOBAL . ')
            AND t.topic_status = ' . ITEM_MOVED . ' ' . $sql_approved;
    $result = $db->sql_query($sql);
    $shadow_topic_list = array();
    while ($row = $db->sql_fetchrow($result)) {
        $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
    }
    $db->sql_freeresult($result);
    // Pick out those shadow topics that the user has no permission to access
    if (!empty($shadow_topic_list)) {
        $sql = 'SELECT t.topic_id, t.forum_id
                FROM ' . TOPICS_TABLE . ' t
                WHERE ' . $db->sql_in_set('t.topic_id', array_keys($shadow_topic_list));
        $result = $db->sql_query($sql);
        while ($row = $db->sql_fetchrow($result)) {
            if ($auth->acl_get('f_read', $row['forum_id'])) {
                unset($shadow_topic_list[$row['topic_id']]);
            }
        }
        $db->sql_freeresult($result);
    }
    // Grab all topic data
    $topic_list = array();
    $sql_limit = $limit;
    // num of topics needs to be return, default is 20, at most 50
    $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . ($sort_dir == 'd' ? 'DESC' : 'ASC');
    $sql_shadow_out = empty($shadow_topic_list) ? '' : 'AND ' . $db->sql_in_set('t.topic_moved_id', $shadow_topic_list, true);
    // If the user is trying to reach late pages, start searching from the end
    $store_reverse = false;
    $unread_sticky_num = $unread_announce_count = 0;
    //get subscribe users
    $user_watch_row = array();
    $sql = 'SELECT * FROM ' . TOPICS_WATCH_TABLE . ' WHERE user_id = ' . $user->data['user_id'];
    $result = $db->sql_query($sql);
    while ($row = $db->sql_fetchrow($result)) {
        $user_watch_row[$row['topic_id']] = $row['notify_status'];
    }
    $db->sql_freeresult($result);
    if (!empty($topic_type)) {
        $sql = 'SELECT t.*, u.user_avatar, u.user_avatar_type,bm.topic_id as bookmarked
                FROM ' . TOPICS_TABLE . ' t
                    LEFT JOIN ' . USERS_TABLE . ' u ON (t.topic_poster = u.user_id)
                    LEFT JOIN ' . BOOKMARKS_TABLE . ' bm ON (bm.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = bm.topic_id) 
                WHERE t.forum_id IN (' . $forum_id . ', 0)
                AND t.topic_type IN (' . $topic_type . ') ' . $sql_shadow_out . ' ' . $sql_approved . '
                ORDER BY ' . $sql_sort_order;
        $result = $db->sql_query_limit($sql, $sql_limit, $start);
    } else {
        if ($user->data['user_id'] != ANONYMOUS) {
            // get total number of unread sticky topics number
            $sql = 'SELECT t.topic_id, t.topic_last_post_time
                    FROM ' . TOPICS_TABLE . ' t
                    WHERE t.forum_id = ' . $forum_id . '
                    AND t.topic_type = ' . POST_STICKY . ' ' . $sql_shadow_out . ' ' . $sql_approved;
            $result = $db->sql_query($sql);
            while ($row = $db->sql_fetchrow($result)) {
                if (empty($forum_id) || empty($row['topic_id'])) {
                    continue;
                }
                $topic_tracking = get_complete_topic_tracking($forum_id, $row['topic_id']);
                if (isset($topic_tracking[$row['topic_id']]) && $topic_tracking[$row['topic_id']] < $row['topic_last_post_time']) {
                    $unread_sticky_num++;
                }
            }
            $db->sql_freeresult($result);
            // get total number of unread announce topics number
            $sql = 'SELECT t.topic_id, t.topic_last_post_time
                    FROM ' . TOPICS_TABLE . ' t
                    WHERE t.forum_id IN (' . $forum_id . ', 0)
                    AND t.topic_type IN (' . POST_ANNOUNCE . ', ' . POST_GLOBAL . ') ' . $sql_shadow_out . ' ' . $sql_approved;
            $result = $db->sql_query($sql);
            while ($row = $db->sql_fetchrow($result)) {
                if (empty($forum_id) || empty($row['topic_id'])) {
                    continue;
                }
                $topic_tracking = get_complete_topic_tracking($forum_id, $row['topic_id']);
                if (isset($topic_tracking[$row['topic_id']]) && $topic_tracking[$row['topic_id']] < $row['topic_last_post_time']) {
                    $unread_announce_count++;
                }
            }
            $db->sql_freeresult($result);
        }
        // get total number of normal topics
        $sql = 'SELECT count(t.topic_id) AS num_topics
                FROM ' . TOPICS_TABLE . ' t
                WHERE t.forum_id = ' . $forum_id . '
                AND t.topic_type = ' . POST_NORMAL . ' ' . $sql_shadow_out . ' ' . $sql_approved;
        $result = $db->sql_query($sql);
        $topics_count = (int) $db->sql_fetchfield('num_topics');
        $db->sql_freeresult($result);
        if ($start > $topics_count / 2) {
            $store_reverse = true;
            if ($start + $sql_limit > $topics_count) {
                $sql_limit = min($sql_limit, max(1, $topics_count - $start));
            }
            // Select the sort order
            $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . ($sort_dir == 'd' ? 'ASC' : 'DESC');
            $start = max(0, $topics_count - $sql_limit - $start);
        }
        $sql = 'SELECT t.*, u.user_avatar, u.user_avatar_type,bm.topic_id as bookmarked
                FROM ' . TOPICS_TABLE . ' t
                    LEFT JOIN ' . USERS_TABLE . ' u ON (t.topic_poster = u.user_id)
                    LEFT JOIN ' . BOOKMARKS_TABLE . ' bm ON (bm.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = bm.topic_id) 
                WHERE t.forum_id = ' . $forum_id . '
                AND t.topic_type = ' . POST_NORMAL . ' ' . $sql_shadow_out . ' ' . $sql_approved . '
                ORDER BY ' . $sql_sort_order;
        $result = $db->sql_query_limit($sql, $sql_limit, $start);
    }
    $tids = array();
    $rowset = array();
    while ($row = $db->sql_fetchrow($result)) {
        $rowset[] = $row;
        $tids[] = $row['topic_moved_id'] ? $row['topic_moved_id'] : $row['topic_id'];
    }
    $db->sql_freeresult($result);
    // get participated users of each topic
    //    get_participated_user_avatars($tids);
    //    global $topic_users, $user_avatar;
    $topic_list = array();
    foreach ($rowset as $row) {
        $replies = $auth->acl_get('m_approve', $forum_id) ? $row['topic_replies_real'] : $row['topic_replies'];
        $short_content = get_short_content($row['topic_first_post_id']);
        $user_avatar_url = get_user_avatar_url($row['user_avatar'], $row['user_avatar_type']);
        $new_post = false;
        if ($user->data['user_id'] != ANONYMOUS) {
            if (empty($forum_id) || empty($row['topic_id'])) {
                continue;
            }
            $topic_tracking = get_complete_topic_tracking($forum_id, $row['topic_id']);
            $new_post = $topic_tracking[$row['topic_id']] < $row['topic_last_post_time'] ? true : false;
        }
        $allow_change_type = $auth->acl_get('m_', $forum_id) || $user->data['is_registered'] && $user->data['user_id'] == $row['topic_poster'] ? true : false;
        $topic_id = $row['topic_moved_id'] ? $row['topic_moved_id'] : $row['topic_id'];
        //        $icon_urls = array();
        //        foreach($topic_users[$topic_id] as $posterid){
        //            $icon_urls[] = new xmlrpcval($user_avatar[$posterid], 'string');
        //        }
        $can_rename = $user->data['is_registered'] && ($auth->acl_get('m_edit', $forum_id) || $user->data['user_id'] == $row['topic_poster'] && $auth->acl_get('f_edit', $forum_id) && ($row['topic_time'] > time() - $config['edit_time'] * 60 || !$config['edit_time']));
        $xmlrpc_topic = new xmlrpcval(array('forum_id' => new xmlrpcval($forum_id), 'topic_id' => new xmlrpcval($row['topic_moved_id'] ? $row['topic_moved_id'] : $row['topic_id']), 'topic_title' => new xmlrpcval(html_entity_decode(strip_tags(censor_text($row['topic_title'])), ENT_QUOTES, 'UTF-8'), 'base64'), 'topic_author_id' => new xmlrpcval($row['topic_first_post_id'], 'string'), 'topic_author_name' => new xmlrpcval(html_entity_decode($row['topic_first_poster_name']), 'base64'), 'last_reply_time' => new xmlrpcval(mobiquo_iso8601_encode($row['topic_last_post_time']), 'dateTime.iso8601'), 'timestamp' => new xmlrpcval($row['topic_last_post_time'], 'string'), 'reply_number' => new xmlrpcval($replies, 'int'), 'view_number' => new xmlrpcval($row['topic_views'], 'int'), 'short_content' => new xmlrpcval($short_content, 'base64'), 'new_post' => new xmlrpcval($new_post, 'boolean'), 'icon_url' => new xmlrpcval($user_avatar_url), 'attachment' => new xmlrpcval($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id) && $row['topic_attachment'] ? 1 : 0, 'string'), 'can_delete' => new xmlrpcval($auth->acl_get('m_delete', $forum_id), 'boolean'), 'can_move' => new xmlrpcval($auth->acl_get('m_move', $forum_id), 'boolean'), 'can_subscribe' => new xmlrpcval(($config['email_enable'] || $config['jab_enable']) && $config['allow_topic_notify'] && $user->data['is_registered'], 'boolean'), 'is_subscribed' => new xmlrpcval(isset($user_watch_row[$topic_id]) ? true : false, 'boolean'), 'can_close' => new xmlrpcval($auth->acl_get('m_lock', $forum_id) || $auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $row['topic_poster'], 'boolean'), 'is_closed' => new xmlrpcval($row['topic_status'] == ITEM_LOCKED, 'boolean'), 'can_stick' => new xmlrpcval($allow_change_type && $auth->acl_get('f_sticky', $forum_id), 'boolean'), 'is_sticky' => new xmlrpcval($row['topic_type'] == POST_STICKY, 'boolean'), 'can_approve' => new xmlrpcval($auth->acl_get('m_approve', $forum_id) && !$row['topic_approved'], 'boolean'), 'is_approved' => new xmlrpcval($row['topic_approved'] ? true : false, 'boolean'), 'can_rename' => new xmlrpcval($can_rename, 'boolean')), 'struct');
        $topic_list[] = $xmlrpc_topic;
        unset($xmlrpc_topic);
    }
    if ($store_reverse) {
        $topic_list = array_reverse($topic_list);
    }
    if (!empty($topic_type)) {
        $topic_num = count($topic_list);
    } else {
        $topic_num = $topics_count;
    }
    $allowed = $config['max_attachments'] && $auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && $config['allow_attachments'] && @ini_get('file_uploads') != '0' && strtolower(@ini_get('file_uploads')) != 'off';
    $max_attachment = $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id) ? 99 : ($allowed ? $config['max_attachments'] : 0);
    $max_png_size = $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id) ? 10485760 : ($allowed ? $config['max_filesize'] === '0' ? 10485760 : $config['max_filesize'] : 0);
    $max_jpg_size = $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id) ? 10485760 : ($allowed ? $config['max_filesize'] === '0' ? 10485760 : $config['max_filesize'] : 0);
    $read_only_forums = explode(",", $config['tapatalk_forum_read_only']);
    $can_post = true;
    if (empty($read_only_forums) || !is_array($read_only_forums)) {
        $read_only_forums = array();
    }
    if (!$auth->acl_get('f_post', $forum_id) || in_array($forum_id, $read_only_forums)) {
        $can_post = false;
    }
    $response = new xmlrpcval(array('total_topic_num' => new xmlrpcval($topic_num, 'int'), 'unread_sticky_count' => new xmlrpcval($unread_sticky_num, 'int'), 'unread_announce_count' => new xmlrpcval($unread_announce_count, 'int'), 'forum_id' => new xmlrpcval($forum_id, 'string'), 'forum_name' => new xmlrpcval(html_entity_decode($forum_data['forum_name']), 'base64'), 'can_post' => new xmlrpcval($can_post, 'boolean'), 'can_upload' => new xmlrpcval($allowed, 'boolean'), 'max_attachment' => new xmlrpcval($max_attachment, 'int'), 'max_png_size' => new xmlrpcval($max_png_size, 'int'), 'max_jpg_size' => new xmlrpcval($max_jpg_size, 'int'), 'topics' => new xmlrpcval($topic_list, 'array')), 'struct');
    return new xmlrpcresp($response);
}
function get_unread_topic_func($xmlrpc_params)
{
    global $db, $auth, $user, $userinfo, $prefix, $config, $mobiquo_config, $phpbb_home;
    $params = php_xmlrpc_decode($xmlrpc_params);
    $start_num = 0;
    $end_num = 19;
    if (isset($params[0]) && is_int($params[0])) {
        $start_num = $params[0];
    }
    // get end index of topic from parameters
    if (isset($params[1]) && is_int($params[1])) {
        $end_num = $params[1];
    }
    // check if topic index is out of range
    if ($start_num > $end_num) {
        return get_error(5);
    }
    // return at most 50 topics
    if ($end_num - $start_num >= 50) {
        $end_num = $start_num + 49;
    }
    $sql_limit = $end_num - $start_num + 1;
    $not_in_fid = '';
    //$ex_fid_ary = array_unique(array_merge(array_keys($auth->acl_getf('!f_read', true)), array_keys($auth->acl_getf('!f_search', true))));
    //if (isset($mobiquo_config['hide_forum_id']))
    //{
    //$ex_fid_ary = array_unique(array_merge($ex_fid_ary, $mobiquo_config['hide_forum_id']));
    //}
    //$not_in_fid = (sizeof($ex_fid_ary)) ? 'WHERE ' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . ';
    $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, forum_order
		FROM ' . $prefix . '_bbforums
		' . $not_in_fid . '
		ORDER BY forum_order';
    $result = $db->sql_query($sql);
    $db->sql_freeresult($result);
    // find out in which forums the user is allowed to view approved posts
    $sql = 'SELECT t.topic_id, t.forum_id, t.topic_last_post_id, p.post_time AS topic_last_post_time FROM ' . $prefix . '_bbtopics t, ' . $prefix . '_bbposts p
		WHERE p.topic_id = t.topic_id AND p.post_time > ' . $userinfo['user_lastvisit'] . ' ORDER BY topic_last_post_time DESC LIMIT ' . $sql_limit . '';
    //if ($fh = fopen('log.txt', 'w'))
    //{
    //fwrite($fh, $userinfo['username']);
    //fclose($fh);
    //}
    $result = $db->sql_query($sql);
    $unread_tids = array();
    while ($row = $db->sql_fetchrow($result)) {
        $topic_id = $row['topic_id'];
        //$forum_id = $row['forum_id'];
        //$topic_tracking = get_complete_topic_tracking($forum_id, $topic_id);
        //if ($topic_tracking[$topic_id] < $row['topic_last_post_time'])
        //{
        $unread_tids[] = $topic_id;
        //}
    }
    $db->sql_freeresult($result);
    $topic_list = array();
    $ur_tids = implode(",", $unread_tids);
    if (count($unread_tids)) {
        $sql = 'SELECT f.forum_id,
			f.forum_name,
			t.topic_id,
			t.topic_title,
			t.topic_replies,
			t.topic_views,
			t.topic_poster,
			t.topic_status,
			t.topic_type,
			t.topic_last_post_id,
			u.user_avatar,
			u.user_avatar_type,
			tw.notify_status,
			p.post_time AS topic_last_post_time,
			u.username AS topic_last_poster_name,
			p.poster_id AS topic_last_poster_id
			FROM ' . $prefix . '_bbtopics t
			LEFT JOIN ' . $prefix . '_bbposts p ON (p.post_id = t.topic_last_post_id)
			LEFT JOIN ' . $prefix . '_bbforums f ON (t.forum_id = f.forum_id)
			LEFT JOIN ' . $prefix . '_users u ON (p.poster_id = u.user_id)
			LEFT JOIN ' . $prefix . '_bbtopics_watch tw ON (tw.user_id = ' . $userinfo['user_id'] . ' AND t.topic_id = tw.topic_id)
			WHERE t.topic_id IN (' . $ur_tids . ')
			ORDER BY topic_last_post_time DESC LIMIT ' . $sql_limit . '';
        $result = $db->sql_query($sql);
        while ($row = $db->sql_fetchrow($result)) {
            $topic_id = $row['topic_id'];
            $forum_id = $row['forum_id'];
            $short_content = get_short_content($row['topic_last_post_id']);
            $user_avatar_url = get_user_avatar_url($row['user_avatar'], $row['user_avatar_type']);
            //$allow_change_type = ($auth->acl_get('m_', $forum_id) || ($user->data['is_registered'] && $user->data['user_id'] == $row['topic_poster'])) ? true : false;
            $xmlrpc_topic = new xmlrpcval(array('forum_id' => new xmlrpcval($forum_id), 'forum_name' => new xmlrpcval(html_entity_decode($row['forum_name']), 'base64'), 'topic_id' => new xmlrpcval($topic_id), 'topic_title' => new xmlrpcval(html_entity_decode(strip_tags($row['topic_title'])), 'base64'), 'reply_number' => new xmlrpcval($row['topic_replies'], 'int'), 'new_post' => new xmlrpcval(true, 'boolean'), 'view_number' => new xmlrpcval($row['topic_views'], 'int'), 'short_content' => new xmlrpcval($short_content, 'base64'), 'post_author_id' => new xmlrpcval($row['topic_last_poster_id']), 'post_author_name' => new xmlrpcval(html_entity_decode($row['topic_last_poster_name']), 'base64'), 'post_time' => new xmlrpcval(mobiquo_iso8601_encode($row['topic_last_post_time']), 'dateTime.iso8601'), 'icon_url' => new xmlrpcval($user_avatar_url), 'can_delete' => new xmlrpcval(false, 'boolean'), 'can_subscribe' => new xmlrpcval(($config['email_enable'] || $config['jab_enable']) && $config['allow_topic_notify'] && $user->data['is_registered'], 'boolean'), 'can_bookmark' => new xmlrpcval($user->data['is_registered'] && $config['allow_bookmarks'], 'boolean'), 'issubscribed' => new xmlrpcval(!is_null($row['notify_status']) && $row['notify_status'] !== '' ? true : false, 'boolean'), 'is_subscribed' => new xmlrpcval(!is_null($row['notify_status']) && $row['notify_status'] !== '' ? true : false, 'boolean'), 'isbookmarked' => new xmlrpcval($row['bookmarked'] ? true : false, 'boolean'), 'can_close' => new xmlrpcval(false, 'boolean'), 'is_closed' => new xmlrpcval($row['topic_status'] == ITEM_LOCKED, 'boolean'), 'can_stick' => new xmlrpcval(false, 'boolean')), 'struct');
            $topic_list[] = $xmlrpc_topic;
        }
        $db->sql_freeresult($result);
    }
    $response = new xmlrpcval(array('total_topic_num' => new xmlrpcval(count($unread_tids), 'int'), 'topics' => new xmlrpcval($topic_list, 'array')), 'struct');
    return new xmlrpcresp($response);
}
function get_topic_func($xmlrpc_params)
{
    $params = php_xmlrpc_decode($xmlrpc_params);
    $forum_id = isset($params[0]) ? intval($params[0]) : 0;
    if (!$forum_id) {
        return get_error(3);
    }
    $offset = 0;
    $limit = 20;
    $topic_type = '0,1,2';
    switch (count($params)) {
        case 4:
            $offset = intval($params[1]);
            // start_num
            $limit = intval($params[2]);
            // end_num
            $topic_type = $params[3] == 'TOP' ? '1' : ($params[3] == 'ANN' ? '2' : $topic_type);
            break;
        case 3:
            $offset = intval($params[1]);
            $limit = intval($params[2]);
            break;
        case 2:
            $topic_type = $params[1] == 'TOP' ? '1' : ($params[1] == 'ANN' ? '2' : $topic_type);
    }
    if ($offset > $limit) {
        # check if topic index is out of range
        return get_error(5);
    } else {
        if ($limit - $offset >= 50) {
            # return at most 50 topics
            $limit = 50;
        } else {
            if (0 === $offset && 0 === $limit) {
                # if both are present and are set to 0, return the first topic only
                $limit = 1;
            } else {
                if ($offset || $limit) {
                    $limit = 1 + $limit - $offset;
                }
            }
        }
    }
    global $db, $prefix;
    $forum = mobi_forums($forum_id);
    $forum = !empty($forum[0]) ? $forum[0] : 0;
    if (!$forum) {
        return get_error(3);
    }
    if (!$forum['auth_read']) {
        get_error(7);
    }
    if (isset($forum['subforums'])) {
        unset($forum['subforums']);
    }
    if (FORUM_LINK == $forum['forum_type']) {
        return get_error(4);
    }
    $result = $db->sql_query("SELECT t.*, u.username, u.user_avatar, u.user_avatar_type, u.user_allowavatar\n\t\tFROM {$prefix}_bbtopics t\n\t\tLEFT JOIN {$prefix}_users u\n\t\tON t.topic_poster=u.user_id\n\t\tWHERE t.forum_id = {$forum_id}\n\t\tAND t.topic_type IN ({$topic_type})\n\t\tORDER BY t.topic_id DESC\n\t\tLIMIT {$limit} OFFSET {$offset}");
    $topic_list = array();
    $unread_sticky_num = $unread_announce_count = 0;
    while ($row = $db->sql_fetchrow($result, SQL_ASSOC)) {
        if (is_user()) {
            if (POST_ANNOUNCE == $row['type']) {
                ++$unread_announce_count;
            } elseif (POST_STICKY == $row['type']) {
                ++$unread_sticky_num;
            }
        }
        $short_content = get_short_content($row['topic_first_post_id']);
        $user_avatar_url = $row['user_allowavatar'] ? get_user_avatar_url($row['user_avatar'], $row['user_avatar_type']) : '';
        $rpc = array('forum_id' => new xmlrpcval($forum_id), 'topic_id' => new xmlrpcval($row['topic_moved_id'] ?: $row['topic_id']), 'topic_title' => new xmlrpcval(html_entity_decode(strip_tags($row['topic_title']), ENT_QUOTES, 'UTF-8'), 'base64'), 'topic_author_id' => new xmlrpcval($row['topic_poster']), 'topic_author_name' => new xmlrpcval(html_entity_decode($row['username']), 'base64'), 'is_subscribed' => new xmlrpcval($forum['auth_read'] && !empty($_SESSION['CPG_SESS']['Forums']['track_topics'][$row['topic_id']]), 'boolean'), 'can_subscribe' => new xmlrpcval($forum['auth_read'], 'boolean'), 'is_closed' => new xmlrpcval(TOPIC_LOCKED == $row['topic_status'], 'boolean'), 'last_reply_time' => new xmlrpcval(mobiquo_iso8601_encode($row['topic_time']), 'dateTime.iso8601'), 'reply_number' => new xmlrpcval($row['topic_replies'], 'int'), 'new_post' => new xmlrpcval(false, 'boolean'), 'view_number' => new xmlrpcval($row['topic_views'], 'int'), 'short_content' => new xmlrpcval(get_short_content($row['topic_first_post_id']), 'base64'));
        if ($user_avatar_url) {
            $rpc['icon_url'] = new xmlrpcval($user_avatar_url);
        }
        $topic_list[] = new xmlrpcval($rpc, 'struct');
    }
    $db->sql_freeresult($result);
    $rpc = array('total_topic_num' => new xmlrpcval($forum['forum_topics'], 'int'), 'forum_id' => new xmlrpcval($forum['forum_id'], 'string'), 'forum_name' => new xmlrpcval(html_entity_decode($forum['forum_name']), 'base64'), 'can_post' => new xmlrpcval($forum['auth_post'], 'boolean'), 'unread_sticky_count' => new xmlrpcval($unread_sticky_num, 'int'), 'unread_announce_count' => new xmlrpcval($unread_announce_count, 'int'), 'can_subscribe' => new xmlrpcval($forum['auth_read'], 'boolean'), 'is_subscribed' => new xmlrpcval($forum['auth_read'] && !empty($_SESSION['CPG_SESS']['Forums']['track_forums'][$forum['forum_id']]), 'boolean'), 'require_prefix' => new xmlrpcval(false, 'boolean'), 'prefixes' => new xmlrpcval(array(), 'array'));
    if ($topic_list) {
        $rpc['topics'] = new xmlrpcval($topic_list, 'array');
    }
    return new xmlrpcresp(new xmlrpcval($rpc, 'struct'));
}