function sp_response($section, $die = true, $status = 'success', $error = '')
{
    global $wpdb;
    $response = array('status' => '', 'type' => '', 'section' => '', 'response' => '', 'error' => '');
    # log the build section and status in the response
    echo "Build upgrade section {$section} executing.  Status: {$status} <br />";
    if ($status == 'error' && !empty($error)) {
        echo "Error: {$error} <br />";
    }
    # build the response
    $response['status'] = $status;
    $response['type'] = 'upgrade';
    $response['section'] = $section;
    $response['error'] = $error;
    $response['response'] = ob_get_contents();
    # save as log meta data if table exists! (Need to check if installed yet sadly)
    $go = $wpdb->get_var("SHOW TABLES LIKE '" . SFLOGMETA . "'");
    if ($go) {
        $sql = '
			INSERT INTO ' . SFLOGMETA . " (version, log_data)\n\t\t\tVALUES (\n\t\t\t'" . SPVERSION . "',\n\t\t\t'" . serialize($response) . "')";
        spdb_query($sql);
    }
    ob_end_clean();
    # send the response (mark with tags so we can extract only the response)
    echo '%%%marker%%%';
    print json_encode($response);
    echo '%%%marker%%%';
    # and if this is the last update in build finish off...
    if (SPBUILD == $section) {
        # let plugins know
        do_action('sph_upgrade_done', SPBUILD);
        # Finished Upgrades ===============================================================================
        sp_log_event(SPRELEASE, SPVERSION, SPBUILD);
        sp_update_permalink(true);
        delete_option('sfInstallID');
        # use wp option table
        # and some final cleanuop tasks
        sp_reset_auths();
        sp_clear_combined_css('all');
        sp_clear_combined_css('mobile');
        sp_clear_combined_css('tablet');
        sp_clear_combined_scripts('desktop');
        sp_clear_combined_scripts('mobile');
        sp_clear_combined_scripts('tablet');
        sp_flush_cache('all');
        sp_reset_member_plugindata();
    }
    if ($die) {
        die;
    }
}
function spa_save_forums_order()
{
    check_admin_referer('forum-adminform_forumorder', 'forum-adminform_forumorder');
    # get the sorted lst
    parse_str($_POST['spForumsOrder'], $list);
    # make sure we have groups
    if (empty($list['group'])) {
        return spa_text('Unable to save group/forum ordering');
    }
    if ($_POST['cgroup'] == 0) {
        # save group sequence
        $gseq = 1;
        foreach ($list['group'] as $gid => $group) {
            $gid = ltrim($gid, 'G');
            $sql = 'UPDATE ' . SFGROUPS . " SET group_seq={$gseq} WHERE group_id={$gid}";
            spdb_query($sql);
            $gseq++;
        }
    }
    # bail if we dont have any forums
    if (empty($list['forum'])) {
        return spa_text('Groups have been reordered');
    }
    # save forum sequence
    $group = 0;
    foreach ($list['forum'] as $id => $parent) {
        # check parent for group or forum
        if (substr($parent, 0, 1) == 'G') {
            $id = ltrim($id, 'F');
            $parent = ltrim($parent, 'G');
            # restart forum sequence if new group id
            if ($group != $parent) {
                $fseq = 1;
                $group = $parent;
            }
            $sql = 'UPDATE ' . SFFORUMS . " SET group_id={$parent}, forum_seq={$fseq}, parent=0, children='' WHERE forum_id={$id}";
            spdb_query($sql);
        } else {
            # forum
            $id = ltrim($id, 'F');
            $parent = ltrim($parent, 'F');
            $sql = 'UPDATE ' . SFFORUMS . " SET group_id={$group}, forum_seq={$fseq}, parent={$parent}, children='' WHERE forum_id={$id}";
            spdb_query($sql);
            # get all children for the parent forum
            $children = array();
            foreach ($list['forum'] as $cid => $cparent) {
                if (substr($cparent, 0, 1) == 'F' && substr($cparent, 1) == $parent) {
                    $children[] = substr($cid, 1);
                }
            }
            $children = serialize($children);
            # update the parent with children info since there is at least one child
            $sql = 'UPDATE ' . SFFORUMS . " SET children='{$children}' WHERE forum_id={$parent}";
            spdb_query($sql);
        }
        $fseq++;
    }
    # clear out group cache tpo enable change_user
    sp_flush_cache('group');
    # done, output message
    return spa_text('Groups and forums have been reordered');
}
function spa_save_housekeeping_data()
{
    check_admin_referer('forum-adminform_housekeeping', 'forum-adminform_housekeeping');
    $mess = '';
    if (isset($_POST['rebuild-fidx'])) {
        $forumid = $_POST['forum_id'];
        if (is_numeric($forumid)) {
            $topics = spdb_table(SFTOPICS, "forum_id={$forumid}");
            if ($topics) {
                include_once SF_PLUGIN_DIR . '/forum/database/sp-db-management.php';
                foreach ($topics as $topic) {
                    sp_build_post_index($topic->topic_id);
                }
                # after reubuilding post indexes, rebuild the forum indexes
                sp_build_forum_index($forumid);
                do_action('sph_toolbox_housekeeping_forum_index');
                $mess = spa_text('Forum indexes rebuilt');
            } else {
                $mess = spa_text('Forum index rebuild failed - no topics in selected forum');
            }
        } else {
            $mess = spa_text('Forum index rebuild failed - no forum selected');
        }
    }
    if (isset($_POST['transient-cleanup'])) {
        include_once SF_PLUGIN_DIR . '/forum/database/sp-db-management.php';
        sp_transient_cleanup();
        do_action('sph_toolbox_housekeeping_transient');
        $mess = spa_text('WP transients cleaned');
    }
    if (isset($_POST['clean-newposts'])) {
        $days = isset($_POST['sfdays']) ? max(sp_esc_int($_POST['sfdays']), 0) : 30;
        $users = spdb_select('col', "SELECT user_id FROM " . SFMEMBERS . " WHERE lastvisit < DATE_SUB(CURDATE(), INTERVAL " . $days . " DAY)");
        if ($users) {
            foreach ($users as $user) {
                spdb_query('UPDATE ' . SFMEMBERS . " SET newposts='a:1:{i:0;i:0;}' WHERE user_id={$user}");
            }
        }
        do_action('sph_toolbox_housekeeping_newpost');
        $mess = spa_text('New posts lists cleaned');
    }
    if (isset($_POST['postcount-cleanup'])) {
        spdb_query('UPDATE ' . SFMEMBERS . ' SET posts = (SELECT COUNT(*) FROM ' . SFPOSTS . ' WHERE ' . SFPOSTS . '.user_id = ' . SFMEMBERS . '.user_id)');
        # force stats to update
        do_action('sph_stats_cron');
        do_action('sph_toolbox_housekeeping_postcount');
        $mess = spa_text('User post counts calculated');
    }
    if (isset($_POST['reset-tabs'])) {
        # clear out current tabs
        $tabs = sp_get_sfmeta('profile', 'tabs');
        sp_delete_sfmeta($tabs[0]['meta_id']);
        # start adding new ones
        spa_new_profile_setup();
        do_action('sph_toolbox_housekeeping_profile_tabs');
        $mess = spa_text('Profile tabs reset');
    }
    if (isset($_POST['reset-auths'])) {
        sp_reset_auths();
        do_action('sph_toolbox_housekeeping_auths');
        $mess = spa_text('Auths caches cleaned');
    }
    if (isset($_POST['reset-plugin-data'])) {
        sp_reset_member_plugindata();
        do_action('sph_toolbox_housekeeping_plugindata');
        $mess = spa_text('Users Plugin Data reset');
    }
    if (isset($_POST['reset-combinedcss'])) {
        sp_clear_combined_css('all');
        sp_clear_combined_css('mobile');
        sp_clear_combined_css('tablet');
        do_action('sph_toolbox_housekeeping_ccombined_css');
        $mess = spa_text('Combined CSS cache file removed');
    }
    if (isset($_POST['reset-combinedjs'])) {
        sp_clear_combined_scripts('desktop');
        sp_clear_combined_scripts('mobile');
        sp_clear_combined_scripts('tablet');
        do_action('sph_toolbox_housekeeping_combined_js');
        $mess = spa_text('Combined scripts cache files removed');
    }
    if (isset($_POST['flushcache'])) {
        sp_flush_cache('all');
        do_action('sph_toolbox_housekeeping_flush_cache');
        $mess = spa_text('General cache flushed');
    }
    do_action('sph_toolbox_housekeeping_save');
    return $mess;
}