function sp_mark_forum_read($forumid)
{
    global $spThisUser;
    # just to be safe, make sure a member called
    if ($spThisUser->member) {
        sp_destroy_users_newposts($forumid);
        sp_update_users_newposts();
    }
}
function sp_track_online()
{
    global $spThisUser, $spVars, $spDevice;
    # dont track feed views
    if ($spVars['pageview'] == 'feed') {
        return;
    }
    # Update tracking
    if ($spThisUser->member) {
        # it's a member
        $trackUserId = $spThisUser->ID;
        $trackName = $spThisUser->user_login;
    } else {
        # Unknown guest
        $trackUserId = 0;
        $trackName = $spThisUser->ip;
    }
    $track = spdb_table(SFTRACK, "trackname='{$trackName}'", 'row');
    $now = current_time('mysql');
    $forumId = isset($spVars['forumid']) ? $spVars['forumid'] : 0;
    $topicId = isset($spVars['topicid']) ? $spVars['topicid'] : 0;
    $pageview = $spVars['pageview'];
    # handle sneak peek
    if (!empty($topicId)) {
        if (!sp_get_auth('view_forum', $forumId)) {
            return;
        }
    } else {
        if (!empty($forumId)) {
            if (!sp_can_view($forumId, 'topic-title')) {
                return;
            }
        }
    }
    # update or start tracking
    if ($track) {
        # they are still here
        spdb_query("UPDATE " . SFTRACK . "\n\t\t\t\t   SET trackdate='" . $now . "', forum_id=" . $forumId . ",  topic_id=" . $topicId . ", pageview='{$pageview}'\n\t\t\t\t   WHERE id=" . $track->id);
        if ($spThisUser->member) {
            sp_update_users_newposts();
        }
        $spThisUser->trackid = $track->id;
        $spThisUser->session_first_visit = false;
        $spThisUser->notification = $track->notification;
    } else {
        # newly arrived
        # set deice being used
        $device = 'D';
        switch ($spDevice) {
            case 'mobile':
                $device = 'M';
                break;
            case 'tablet':
                $device = 'T';
                break;
            case 'desktop':
                $device = 'D';
                break;
        }
        # display classes
        $display = 'spType-' . $spThisUser->usertype;
        if (!empty($spThisUser->rank)) {
            $display .= ' spRank-' . sp_create_slug($spThisUser->rank[0]['name'], false);
        }
        if (!empty($spThisUser->special_rank)) {
            foreach ($spThisUser->special_rank as $rank) {
                $display .= ' spSpecialRank-' . sp_create_slug($rank['name'], false);
            }
        }
        if (!empty($spThisUser->memberships)) {
            foreach ($spThisUser->memberships as $membership) {
                $display .= ' spUsergroup-' . sp_create_slug($membership['usergroup_name'], false);
            }
        }
        spdb_query("INSERT INTO " . SFTRACK . "\n\t\t\t \t   (trackuserid, trackname, forum_id, topic_id, trackdate, pageview, device, display) VALUES\n\t\t\t \t   ({$trackUserId}, '{$trackName}', {$forumId}, {$topicId}, '{$now}', '{$pageview}', '{$device}', '{$display}')");
        $spThisUser->trackid = $spVars['insertid'];
        $spThisUser->session_first_visit = true;
        if ($spThisUser->member) {
            sp_update_users_newposts();
        }
    }
    # Check for expired tracking - some may have left the scene
    $splogin = sp_get_option('sflogin');
    $timeout = $splogin['sptimeout'];
    if (!$timeout) {
        $timeout = 20;
    }
    $expired = spdb_table(SFTRACK, "trackdate < DATE_SUB('{$now}', INTERVAL {$timeout} MINUTE)");
    if ($expired) {
        # if any Members expired - update user meta
        foreach ($expired as $expire) {
            if ($expire->trackuserid > 0) {
                sp_set_last_visited($expire->trackuserid);
            }
        }
        # finally delete them
        spdb_query("DELETE FROM " . SFTRACK . "\n\t\t\t\t\tWHERE trackdate < DATE_SUB('{$now}', INTERVAL {$timeout} MINUTE)");
    }
}